У меня есть модель товара и модель фотографий (они связаны через foreignkey). Как правильно задать фильтр чтобы на странице каждого товара были только те фотографии которые связанны с данным товаром.
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/popper.js@1.16.0/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>