Django:处理模板页面中外键请求的最佳方式
Django: best way to handle foreign key requests in template pages
假设您正在制作一个网站来简单地列出您的产品。
您想为您的每件产品上传数量不详的图片。所以你,按照 Django 的多对一文档,制作两个模型:
# files stored under my_app/static/my_app/product_images/product_<id>/<img_name>
def product_img_dir_path(instance, filename):
return 'my_app/static/my_app/product_images/product_{0}/{1}'.format(instance.product.id, filename)
class Product(models.Model):
name = models.CharField ...
... # other attributes of the product, e.g. price, etc
class ProductImage(models.Model):
product = models.ForeignKey("Product", on_delete=models.CASCADE)
image = models.ImageField(upload_to=product_img_dir_path)
现在,如果我想要产品 1 的所有图片,我可以使用以下方法检索它们:
ProductImages.objects.filter(product__pk=1)
我的问题从这里开始。
假设您想要一个索引页面,它只显示您所有产品的列表,并且为简单起见,显示与每个产品关联的第一张图片。
你用
制作了一个模板页面
{% for product in product list %}
<div class="product-listing" style="display:inline">
<!-- image for product goes here -->
<!-- brief description goes here -->
</div>
{% endfor %}
在您的上下文中传递 product_list
的位置:
# inside /my_app/views.py
def index(request):
...
context = {"product_list": Product.objects.all()}
...
问题:在模板页面中显示图像的同时访问图像的最佳方式是什么?
目前我认为构建一个并行图像列表就足够了:
# inside /my_app/views.py
def index(request):
...
product_list = Product.objects.all()
image_list = [product.productimage_set.all()[0] for product in product_list]
context = {"product_list": product_list, "image_list": image_list}
...
然后以某种方式使用 forloop 计数器获取产品的相应图像。
例如
{% for product in product list %}
<div class="product-listing" style="display:inline">
<img src="{{ image_list[<forloop counter>].image.url }}" />
<!-- brief description goes here -->
</div>
{% endfor %}
有更好的方法吗?
只要您可以访问 product.productimage_set
,您就可以尝试在模板中对其进行迭代,不要将其作为视图上下文传递。
在您的 Django 模板中:
{% for product in product_list %}
<div class="product-listing" style="display:inline">
{% for product_image in product.productimage_set.all %}
<img src="{{ product_image.image.url }}" />
<!-- brief description goes here -->
{% endfor %}
</div>
{% endfor %}
我认为如果您通过将图像移动到您的产品模型来简化您的设计,您将更容易解决这个问题。
如果要保存图片的路径,使用 CharField 会更容易,但如果要保存许多路径,为什么不使用 JSONField?
我的建议是这样的:
class Product(models.Model):
name = models.CharField(null=True, blank=True)
main_image = models.CharField(null=True, blank=True) # Optional
images = JSONField(null=True, blank=True)
假设您正在制作一个网站来简单地列出您的产品。
您想为您的每件产品上传数量不详的图片。所以你,按照 Django 的多对一文档,制作两个模型:
# files stored under my_app/static/my_app/product_images/product_<id>/<img_name>
def product_img_dir_path(instance, filename):
return 'my_app/static/my_app/product_images/product_{0}/{1}'.format(instance.product.id, filename)
class Product(models.Model):
name = models.CharField ...
... # other attributes of the product, e.g. price, etc
class ProductImage(models.Model):
product = models.ForeignKey("Product", on_delete=models.CASCADE)
image = models.ImageField(upload_to=product_img_dir_path)
现在,如果我想要产品 1 的所有图片,我可以使用以下方法检索它们:
ProductImages.objects.filter(product__pk=1)
我的问题从这里开始。
假设您想要一个索引页面,它只显示您所有产品的列表,并且为简单起见,显示与每个产品关联的第一张图片。
你用
制作了一个模板页面{% for product in product list %}
<div class="product-listing" style="display:inline">
<!-- image for product goes here -->
<!-- brief description goes here -->
</div>
{% endfor %}
在您的上下文中传递 product_list
的位置:
# inside /my_app/views.py
def index(request):
...
context = {"product_list": Product.objects.all()}
...
问题:在模板页面中显示图像的同时访问图像的最佳方式是什么?
目前我认为构建一个并行图像列表就足够了:
# inside /my_app/views.py
def index(request):
...
product_list = Product.objects.all()
image_list = [product.productimage_set.all()[0] for product in product_list]
context = {"product_list": product_list, "image_list": image_list}
...
然后以某种方式使用 forloop 计数器获取产品的相应图像。
例如
{% for product in product list %}
<div class="product-listing" style="display:inline">
<img src="{{ image_list[<forloop counter>].image.url }}" />
<!-- brief description goes here -->
</div>
{% endfor %}
有更好的方法吗?
只要您可以访问 product.productimage_set
,您就可以尝试在模板中对其进行迭代,不要将其作为视图上下文传递。
在您的 Django 模板中:
{% for product in product_list %}
<div class="product-listing" style="display:inline">
{% for product_image in product.productimage_set.all %}
<img src="{{ product_image.image.url }}" />
<!-- brief description goes here -->
{% endfor %}
</div>
{% endfor %}
我认为如果您通过将图像移动到您的产品模型来简化您的设计,您将更容易解决这个问题。 如果要保存图片的路径,使用 CharField 会更容易,但如果要保存许多路径,为什么不使用 JSONField?
我的建议是这样的:
class Product(models.Model):
name = models.CharField(null=True, blank=True)
main_image = models.CharField(null=True, blank=True) # Optional
images = JSONField(null=True, blank=True)