E
E
evgenii-del2020-02-08 14:17:43
Django
evgenii-del, 2020-02-08 14:17:43

Django more than one image?

I have a product model and a photo model (they are linked via foreignkey). How to correctly set the filter so that on the page of each product there are only those photos that are associated with this product.

models.py

from django.db import models
from django.urls import reverse


class Category(models.Model):
    name = models.CharField(max_length=200, db_index=True)
    slug = models.SlugField(max_length=200, unique=True)

    class Meta:
        ordering = ('name',)
        verbose_name = 'category'
        verbose_name_plural = 'categories'

    def __str__(self):
        return self.name

    def get_absolute_url(self):
        return reverse('shop:product_list_by_category', args=[self.slug])

class Product(models.Model):
    category = models.ForeignKey(Category, related_name='products', on_delete=models.CASCADE)
    name = models.CharField(max_length=200, db_index=True)
    slug = models.SlugField(max_length=200, db_index=True)
    image = models.ImageField(upload_to='products/%Y/%m/%d', blank=True)
    description = models.TextField(blank=True)
    price = models.DecimalField(max_digits=10, decimal_places=2)
    available = models.BooleanField(default=True)
    created = models.DateTimeField(auto_now_add=True)
    updated = models.DateTimeField(auto_now=True)

    class Meta:
        ordering = ('name',)
        index_together = (('id', 'slug'),)

    def __str__(self):
        return self.name

    def get_absolute_url(self):
        return reverse('shop:product_detail', args=[self.id, self.slug])

# Картинки
class Photo(models.Model):
    image = models.ImageField(upload_to='products/%Y/%m/%d', blank=True)
    location = models.ForeignKey(Product, on_delete=models.CASCADE)


views.py

from django.shortcuts import render, get_object_or_404
from .models import Category, Product, Photo
from cart.forms import CartAddProductForm


def product_list(request, category_slug=None):
    category = None
    categories = Category.objects.all()
    products = Product.objects.filter(available=True)

    if category_slug:
        category = get_object_or_404(Category, slug=category_slug)
        products = products.filter(category=category)

    return render(request, 'shop/product/list.html',
            {'category': category,
            'categories': categories,
            'products': products})

def product_detail(request, id, slug):
    product = get_object_or_404(Product, id=id, slug=slug, available=True)
    # Как правильно задать filter тут?????
    photos = Photo.objects.all()
    cart_product_form = CartAddProductForm()
    return render(request, 'shop/product/detail.html', {'product': product,
                                                        'cart_product_form': cart_product_form,
                                                        'photos': photos})


detail.html

{% load static %}
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous">
  <link href="{% static "css/main.css" %}" rel="stylesheet">
  <title>{% block title %}My shop{% endblock %}</title>
</head>
<body>
  <header class="header">
    <nav class="header-navbar navbar navbar-expand-lg navbar-dark nav-detail">
      <div class="container">
        <a class="navbar-brand" href="/">SHOP</a>
        <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#header-navbar-collapse" aria-controls="header-navbar-collapse" aria-expanded="false" aria-label="Toggle navigation">
          <span class="navbar-toggler-icon"></span>
        </button>
        <div class="collapse navbar-collapse justify-content-end" id="header-navbar-collapse">
          <ul class="navbar-nav">
            <li class="nav-item">
              <a class="nav-link" href="#about">About us</a>
            </li>
            <li class="nav-item">
              <a class="nav-link" href="#gallery">Gallery</a>
            </li>
            <li class="nav-item">
              <a class="nav-link" id="btn_modal_window">Cart</a>
              <div id="my_modal" class="modal">
                <div class="modal_content">
                  <span class="close_modal_window">×</span>
                  <div class="cart">
                    {% with total_items=cart|length %}
                    {% if cart|length > 0 %}
                    Your cart:
                    <a href="{% url "cart:cart_detail" %}">
                      {{ total_items }} item{{ total_items|pluralize }},
                      ${{ cart.get_total_price }}
                    </a>
                    {% else %}
                    Your cart is empty.
                    {% endif %}
                    {% endwith %}
                  </div>
                </div>
              </div>
            </li>
          </ul>
        </div>
      </div>
    </nav>
    <div class="container">
      <div class="row">
        <div class="col-5">
          <img class='product-image' src="{{ product.image.url }}">
        </div>
        <div class="col-7">
          <h1>{{ product.name }}</h1>
          <hr>
          <h2>
            <a href="{{ product.category.get_absolute_url }}">{{ product.category }}</a>
          </h2>
          <p class="price">${{ product.price }}</p>
          {{ product.description|linebreaks }}
          <div class="">
            <form action="{% url "cart:cart_add" product.id %}" method="post">
              {{ cart_product_form }}
              {% csrf_token %}
              <input type="submit" value="Add to cart">
            </form>
          </div>
          <div class="row">
            {% for photo in photos %}
              <div class="col-4">
                <img class="detail-img" src="{{ photo.image.url }}">
              </div>
            {% endfor %}
          </div>
        </div>
      </div>
    </div>
    <footer>
      <div class="container">
        <p class="float-right">
          <a href="#">Наверх</a>
        </p>
        <p>Album example is © Bootstrap, but please download and customize it for yourself!</p>
        <p>Первый раз на сайте? <a href="">Зарегестрироваться</a> or read our <a href="">Связь с нами</a>.</p>
      </div>
    </footer>
    <script src="{% static "js/main.js" %}"></script>
    <script src="https://code.jquery.com/jquery-3.4.1.slim.min.js" integrity="sha384-J6qa4849blE2+poT4WnyKhv5vZF5SrPo0iEjwBvKU7imGFAV0wwj1yYfoRSJoZ+n" crossorigin="anonymous"></script>
    <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/umd/popper.min.js" integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" crossorigin="anonymous"></script>
    <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js" integrity="sha384-wfSDF2E50Y2D1uUdj0O3uMBJnjuUD4Ih7YwaYd1iqfktj0Uod8GCExl3Og8ifwB6" crossorigin="anonymous"></script>
  </body>
  </html>

Answer the question

In order to leave comments, you need to log in

1 answer(s)
D
Dr. Bacon, 2020-02-08
@evgenii-del

write a bunch of code and not be able to use filter, wtf?
photos = Photo.objects.filter(location=product)
1. well, right away, what a fright to call the location field when all normal people call it product
2. and there is also a “backward” relationship so as not to start the photos variable

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question