Django - 模特FK / many2many关系

时间:2012-03-08 05:31:52

标签: django many-to-many relationship reverse

我需要更好地了解FK / m2m关系如何运作。 我已准备好用于上传图像的图像模型,它还有一个附加功能 - 可以通过添加到特定图库(m2m与图库的关系)进行分类。

要访问图库名称,我只需要执行查询集,例如:

Images.objects.filter(gallery__gallery_name = '')

我想稍微颠倒查询,所以从Gallery模型我可以访问特定图库中的图片(gallery_name)。

我怎么能这样做?

型号:

class Images(models.Model):
   image = models.ImageField(upload_to=update_filename, blank=True, null=True, verbose_name="Obrazek")
   gallery = models.ForeignKey('Gallery', blank=True, null=True)

class Gallery(models.Model):
    gallery_name = models.CharField(max_length=128)
    gallery_description = models.TextField(blank=True, null=True)

查看:

def index(request):
    p = Gallery.objects.filter(gallery_name="main").order_by('-id')
    return TemplateResponse(request, 'gallery.html', 
                                    {'gallery': p,
                                    },)

模板:

{% for n in gallery.all %}
<h2 class="center">{{n.gallery_name}}</h2>
<hr>
    {% for n in gallery.images_set %}
       <div class="grid_4">
        {{ n.image }}
       </div>
{% endfor%}

3 个答案:

答案 0 :(得分:1)

问题在于模板中的{% for n in gallery.images_set %}位。 images_set是一个相关的经理,而不是一个查询集。要获取查询集,您需要调用all或其他返回查询集的DBAPI方法。所以,只需将其更改为gallery.images_set.all,就可以了。

答案 1 :(得分:1)

尝试以下方面的内容:

# models.py
class Gallery(models.Model):
    name = models.CharField(max_length=30)
    description = models.CharField(max_length=200, null=True)
    images = models.ManyToMany(Image)

class Image(models.Model):
    title = models.CharField(max_length=30)
    caption = models.CharField(max_length=200, null=True)
    image = models.ImageField(upload_to=SOMEPLACE_FOR_MEDIA)

从这里你应该能够做到这样的事情:

image = Image.objects.get(title="Girl Holding Cheese")
related_galleries = image.gallery_set.all()

或类似的东西,以拉动你想要的东西。反过来也是这样。要拉动图库中的所有图像,您可以

gallery = Gallery.objects.get(name="Cheesy Wimmin")
related_images = gallery.images.all()

虽然最后的作业不是必需的,但我通常直接传递gallery.images.all()或image.gallery_set.all()。请注意 not 包含M2M定义的对象的引用末尾的“_set”。

关于直接使用的主题,您可以进行复合参考,例如

Image.objects.get(title="Girl Holding Cheese").gallery_set.all()

同样,但你必须决定何时使代码更加清晰简洁,以及何时使代码更难以阅读。

我希望这会让你朝着正确的方向前进。

更新

在下面的评论中,您注意到您无法做到

images = Images.objects.filter(gallery_set="Cheesy Wimmins")
related_galleries = images.gallery_set.all()

这是因为您将尝试在查询集上过滤()或all(),而不是单个模型。因此,要使其工作,您可以在模板中使用for循环。像

这样的东西
# views.py
galleries = Gallery.objects.all()
return render(request, 'some/template.html', {'galleries': galleries})

然后

<!-- templates/some/template.thml -->
{% for gallery in galleries %}
    <div class="gallery">
    <h2>{{ gallery.name }}</h2>
    {% for item in gallery.images.all %}
        <div class="image">
            {{ item.image }}
        </div>
    {% endfor %}
    </div>
{% endfor %}

或类似的东西。当然,您需要执行任何您希望使其看起来正确的格式化步骤,但这是获取数据的方法。

答案 2 :(得分:1)

galleryQuerySet - 它没有images_set

这是更恰当地命名变量的地方,可以轻松地开始预防这些问题:例如,galleries更适合于Gallery对象列表...然后,galleries.images_set会立即引发红色标志。

无论如何,您需要拨打images_set来调用您所谓的n

{% for n in gallery.all %}
<h2 class="center">{{n.gallery_name}}</h2>
<hr>
    {% for n in n.images_set.all %} 
       <div class="grid_4">
        {{ n.image }}
       </div>
{% endfor%}