【问题标题】:Django template loop through items with parent ID or PKDjango 模板循环遍历具有父 ID 或 PK 的项目
【发布时间】:2019-06-21 20:14:29
【问题描述】:

我正在尝试在 django 上设置 magnific popup。 我的目标是在主页概览图库视图中显示一张主图片,单击该图片时会打开一个弹出窗口,其中包含来自同一张照片的相关图片,即具有相同 ID 或 PK 的图片。

我尝试申请following approach 但我就是无法让它工作,也许有人可以帮我解决这个问题

我的模型.py

class Item(models.Model):
name           = models.CharField(blank=False, max_length=200)    
category       = models.ForeignKey(Category, blank=True, null=True, on_delete=models.SET_NULL)
order          = models.IntegerField(blank=True, null=True)
active         = models.BooleanField(blank=True, default=False)
objects        = models.Manager()

class Meta:
    verbose_name_plural = 'items'

def __str__(self):
    return self.name

class ItemImage(models.Model):
image          = ProcessedImageField( 
                                blank=True, 
                                null=True,
                                processors=[ResizeToFit(width=1680, upscale=False)],
                                format='JPEG',
                                options={'quality':90})
order          = models.IntegerField(blank=True, null=True)
main           = models.BooleanField(blank=True, default=False)
cover          = models.BooleanField(blank=True, default=False)
item           = models.ForeignKey(Item, related_name='items', blank=True, null=True, on_delete=models.SET_NULL)
objects        = models.Manager()

class Meta:
    verbose_name_plural = 'item images'

Views.py

def portraits(request):
port = ItemImage.objects.filter(item__category__slug='portraits', item__active=True, main=True,).order_by('item__order')
portall = ItemImage.objects.filter(item__category__slug='portraits', item__active=True).order_by('item__order')
context = {
    'main_portraits': port,
    'all_portraits': portall
        }
return render(request, 'gallery/portraits.html', context)

和模板:

{% block content %}

<div class="grid">
  {% for pic in main_portraits %}
    <div class="item">
      <div class="item">
          <div class="outer-text">
            <div class="text">
              {{ pic.item.name }}
              <p>Click to view gallery</p>
            </div>
          </div>
          <a><img class="lazy" alt=""
          sizes="(min-width:1400px) 1220px
                (min-width:1000px) 1000px,
                (min-width:500px) 700px,
                (min-width:320px) 420px,
                280px"
          srcset="{{ pic.image_xs.url }} 280w, 
                  {{ pic.image_s.url }} 420w,
                  {{ pic.image_m.url }} 700w,
                  {{ pic.image_l.url }} 1000w,
                  {{ pic.image_xl.url }} 1220w" />
          </a> {{ pic.item.pk }}
      </div>                
      <div class="lazy">
        {% for p in all_portraits %}
          <a href="{{ z.item.pk }}"></a>
        {% endfor %}
      </div>
    </div>
  {% endfor %}
</div>

{% endblock %}

我已经设置了

z.item.pk 

只是作为一个测试,看看我的任何操作是否会导致 pk 聚集在一起。例如,第一个 for-loop 返回一个 PK “24”的图片,我需要第二个 for-lop 只返回具有相同 PK 的图片;对于每张图片也是如此。我认为答案可能与 _set.all 函数有关,就像上面的相关问题一样,但我似乎无法让它在我的情况下工作。感觉好像我在这里遗漏了一些东西。

当前输出:

<div class="grid">

    <div class="item">
      <div class="item">
          <div class="outer-text">
            <div class="text">
              Palagā tītā
              <p>Click to view gallery</p>
            </div>
          </div>
          <a><img class="lazy" alt=""
          sizes="(min-width:1400px) 1220px
                (min-width:1000px) 1000px,
                (min-width:500px) 700px,
                (min-width:320px) 420px,
                280px"
          srcset="/media/CACHE/images/IMG_8329_3Vi8mYO_GD621ql/958ba5dbee5efe28fd2f5054b8f819e1.jpg 280w, 
                  /media/CACHE/images/IMG_8329_3Vi8mYO_GD621ql/02d12ca7f0633fee2fc762cf96f7889e.jpg 420w,
                  /media/CACHE/images/IMG_8329_3Vi8mYO_GD621ql/ba5fa6633e92a288e3b2f47a713d64c2.jpg 700w,
                  /media/CACHE/images/IMG_8329_3Vi8mYO_GD621ql/fe0d559fef5b02434c43f841005d4961.jpg 1000w,
                  /media/CACHE/images/IMG_8329_3Vi8mYO_GD621ql/96d0e52dff14d1bc4b60bbec674565db.jpg 1220w" />
          </a> 24
      </div>                
      <div class="lazy">

          <a href="24"></a>

          <a href="24"></a>

          <a href="24"></a>

          <a href="26"></a>

          <a href="27"></a>

          <a href="27"></a>

          <a href="30"></a>

          <a href="31"></a>

      </div>
    </div>

【问题讨论】:

  • 每个项目可以有多少主图像?
  • 从技术上讲,所有图像都可以是“主要”图像,因为它们会出现在画廊视图中,但我们的想法是每个摄影相册都有一个主图像。所有图片都是通过管理员以相同的方式添加的,其中一张将被“选中”,将其标记为相册的主要缩略图。
  • 我认为改变模型设计更好。
  • 我的模型已经被证明非常实用,这是最后一块拼图,我相信有办法解决它

标签: django django-models django-templates django-views


【解决方案1】:

在移交给模板之前,您需要包含每个主图像的相关图像的预过滤查询集。

def portraits(request):
    ports = ItemImage.objects.filter(item__category__slug='portraits', item__active=True, main=True,).order_by('item__order')
    for p in ports:
        # You may not need the item__category__slug filter 
        # if there are only images of the same category 
        # associated with an item.
        # Also, if you want to exclude the main image 
        # from the set of related images, you need to add the filter
        # main=False

        p.related_images = ItemImage.objects.filter(item__category__slug='portraits', item__id=p.item.id)

    context = {
        'main_portraits': ports,
            }
    return render(request, 'gallery/portraits.html', context)

然后就可以在模板中循环遍历main_portraits,在嵌套循环中获取每个主图的相关图片:

{% for mainp in main_portraits %}
    {% for im in mainp.related_images %}
         {# do something with the related images #}
    {% endfor %}
{% endfor %}

【讨论】:

    【解决方案2】:

    您可以像这样分解模型,这将使​​查询更容易。

    # models.py
    class Item(mdoels.Model):
        name = models.CharField(blank=False, max_length=200)
        category = models.ForeignKey(Category, blank=True, null=True, on_delete=models.SET_NULL)
        ...
        display_image = models.ProcessedImageField(...)
    
    
    class ItemImage(models.Model):
        item = models.ForeignKey(Item, related_name='images', blank=True, null=True, on_delete=models.SET_NULL)
        image = models.ProcessedImageField(...)
        ...
    
    
    #views.py
    def portraits(request):
        items = Item.objects.filter(category__slug='portraits', active=True)
        return render(request, 'gallery/portraits.html', context={items: items})
    
    #template
    {% for item in items %}
    
        <h1> {{item.name}} </h1>
        <img src={{item.display_image}} />
    
        {% for item_image in item.images.all %}
            <img src={{item_image.image}} />
        {% endfor %}
    
    {% endfor %}
    

    【讨论】:

    • 这可行,但不完全是我想要的。谢谢你!
    猜你喜欢
    • 2019-06-20
    • 2018-06-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-13
    • 2023-02-26
    • 1970-01-01
    • 2016-08-31
    相关资源
    最近更新 更多