Django:处理模板页面中的外键请求的最佳方法

时间:2017-08-16 09:22:40

标签: python django python-3.4

假设您正在制作一个网站,只需列出您的产品。

您希望为每个产品上传未指定数量的图片。因此,按照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计数器获取产品的相应图像。

e.g。

{% 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 %}

有更好的方法吗?

2 个答案:

答案 0 :(得分:1)

只要您可以访问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 %}

答案 1 :(得分:0)

如果您通过将图像移动到产品模型来简化设计,我认为解决此问题会更容易。 如果要保存图像的路径,使用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)