Django - 根据外键列出项目

时间:2018-02-07 17:38:57

标签: python django

我是python的新手,Django(以及一般的编程)。我已经花了10多个小时来解决这个问题,但我似乎错过了一些东西。

我在Django中有两个模型 - 文章和类别,我在views.py文件中使用ListView和DetailsView。在articles_details页面上,我试图列出与当前文章属于同一类别的所有文章。

我已经尝试了一百万件事,但无济于事。我想我可以使用__exact来定义一个函数,根据articles.category(当前文章的类别)的当前值来过滤类别数据库。不过,我不知道怎么做,以及如何在我的模板中调用这样的函数。

有人可以协助吗?提前谢谢你。

P.S。:不确定部分问题是否使用ListView和DetailsView。这是我的代码:

Views.py

    from django.shortcuts import render
from web import models
from web.models import Main, Series_rh, Articles_rh
from django.views.generic import View,TemplateView,ListView,DetailView

class IndexView(TemplateView):
    template_name = 'web/index.html'

class CategoriesView(ListView):
    model = models.Series_rh
    template_name = 'web/series.html'
    context_object_name = 'Categories_rh_list'

class CategoriesView(DetailView):
    model = models.Series_rh
    template_name = 'web/series.html'
    context_object_name = 'Categories_rh_details'

class ArticlesListView(ListView):
    model = models.Articles_rh
    template_name = 'web/articles-list.html'
    context_object_name = 'Artciles_rh_list'

class ArticlesDetailView(DetailView):
    model = models.Articles_rh
    template_name = 'web/articles-details.html'
    context_object_name = 'Articles_rh_details'

Models.py

from django.db import models

    class Categories_rh(models.Model):
        name = models.CharField(max_length=55)
        title = models.CharField(max_length=250)
        description = models.TextField()
        image = models.ImageField(upload_to='static/media/')

        def __str__(self):
            return self.name

    class Articles_rh(models.Model):
        para_one = models.TextField()
        para_two = models.TextField()
        image = models.ImageField(upload_to='static/media/')
        featured = models.BooleanField(default=False)
        categories = models.ForeignKey(Categories_rh, on`_delete='models.SET_NULL', blank=True, null=True, rela`ted_name='categories_for_articles')

        def __str__(self):
            return self.name

1 个答案:

答案 0 :(得分:2)

您需要在 web / articles-details.html 文件中执行以下操作:

{% for article in Articles_rh_details.categories.categories_for_articles.all %}
  <p>{{ article.para_one }}</p>
{% endfor %}

现在,为什么会这样:

Articles_rh_details是您通过Articles_rh属性在ArticlesDetailView中为context_object_name模型实例命名的方式。

由此,我们可以访问Articles_rh的属性categories,这是您与Categories_rh模型的关系。

在此关系中,您将related_name属性设置为categories_for_articles。这实际上是与此特定类别相关的所有文章的反向关系的名称

由于它会返回QuerySet,我们要么调用all()方法,要么filter()order_by()等等。但是,因为我们在模板,我们可以做的不多,只需调用all()方法。

最终结果将是与此类别相关的所有文章的列表。

我建议您将此反向关系(related_name)重命名为articles而不是categories_for_articles。它会更自然。另外,categories关系如果是category(单数)则更自然,因为关系只有一个类别。最后,context_object_name可能只是article。这样你就可以访问所需的文章组:

{% for related_article in article.category.articles.all %}
    {{ related_article.para_one }}
{% endfor %}

一些提高代码可读性的一般建议。 : - )