在 Django 模板中分页时,如何正确显示与其父模型字段关联的所有内联字段?

Cap*_*awn 6 django django-templates django-pagination django-listview

我是一名学生,也是 Django 新手,我们有一个项目正在尝试使用 Django 构建。在构建该项目的过程中,我偶然发现了一个问题,并陷入困境数周。

\n

我想在分页时在一页上显示与其父字段关联的所有内联字段。当我尝试使用两个具有外键的附加模型对模型进行分页时,我的模板中得到了一个奇怪的结果。我似乎不知道如何解决它。我在网上尝试了多种方法,也阅读了很多论坛和讨论,但都没有效果,到目前为止都没有效果。以下是我的文件和一些图片:

\n
\n

(模型.py)

\n
from django.db import models\n\nclass History(models.Model):\n   BARANGAY = (\n     (\'Alegria\',\'Alegria\'),\n     (\'Bagacay\',\'Bagacay\'),\n     (\'Baluntay\',\'Baluntay\'),\n     (\'Datal Anggas\',\'Datal Anggas\'),\n     (\'Domolok\',\'Domolok\'),\n     (\'Kawas\',\'Kawas\'),\n     (\'Ladol\',\'Ladol\'),\n     (\'Maribulan\',\'Maribulan\'),\n     (\'Pag-Asa\',\'Pag-Asa\'),\n     (\'Paraiso\',\'Paraiso\'),\n     (\'Poblacion\',\'Poblacion\'),\n     (\'Spring\',\'Spring\'),\n     (\'Tokawal\',\'Tokawal\')\n   )\n  barangay_name = models.CharField(max_length=100,choices=BARANGAY,default=\'Alegria\')\n  barangay_img = models.ImageField(upload_to=\'history_imgs\',blank=True)\n  barangay_info = models.TextField()\n\nclass GeoHazard(models.Model):\n  history = models.ForeignKey(History,related_name=\'geohazards\',on_delete=models.CASCADE)\n  geohazard_img = models.ImageField(upload_to=\'history_imgs\',blank=True)\n  date_published = models.CharField(max_length=100, null=True)\n  geohazard_info = models.TextField()\n\nclass Assessment(models.Model):\n   RATINGS = (\n      (\'HIGH\',\'HIGH\'),\n      (\'HIGH (Mitigated)\',\'HIGH (Mitigated)\'),\n      (\'MODERATE\',\'MODERATE\'),\n      (\'MODERATE (Mitigated)\',\'MODERATE (Mitigated)\'),\n      (\'LOW\',\'LOW\'),\n      (\'UNKNOWN\',\'UNKNOWN\'),\n   )\n\n   history = models.ForeignKey(History,related_name=\'assessment\',on_delete=models.CASCADE)\n   purok_name = models.CharField(max_length=50)\n   purok_coordinates = models.CharField(max_length=100,default=\'unknown\')\n   flood_rating = models.CharField(max_length=100,choices=RATINGS,default=\'UNKNOWN\')\n   landslide_rating = models.CharField(max_length=100,choices=RATINGS,default=\'UNKNOWN\')\n
Run Code Online (Sandbox Code Playgroud)\n

在我的 models.py 中,我有父模型“History”和两个附加模型“GeoHazard”和“Assessment”,两者都有外键。

\n
\n

管理仪表板.png

\n

(管理员.py)

\n
from django.contrib import admin\n\nfrom auxiliary.models import (\n   History, \n   GeoHazard,\n   Assessment\n)\nclass GeoHazardInline(admin.StackedInline):\n   model = GeoHazard\n   extra = 0\n\nclass AssessmentInline(admin.StackedInline):\n   model = Assessment\n   extra = 0\n\nclass HistoryAdmin(admin.ModelAdmin):\n   inlines = [GeoHazardInline,AssessmentInline]\n\nadmin.site.register(History,HistoryAdmin)\n
Run Code Online (Sandbox Code Playgroud)\n

在我的 admin.py 中,我使用“StackedInline”。我以这种方式构建它,以便父模型“History”可以有多个与其关联的内联字段。

\n
\n

(views.py#1)

\n
class history(ListView):\n   model = History\n   template_name = \'auxiliary/history.html\'\n   context_object_name = \'histories\'\n   paginate_by = 1\n
Run Code Online (Sandbox Code Playgroud)\n

最初,我使用“ListView”来利用其预构建的分页方法“paginate_by”,但这样做的模板结果就是这样(见下图)。正如你们所看到的,内联字段也按“1”进行分页,并且其他内联字段与第一页分开。

\n

模板视图1.png)

\n
\n

(views.py #2)

\n
class HistoryView(ListView):\n   model = History\n   template_name = \'auxiliary/history.html\'\n   context_object_name = \'histories\'\n   paginate_by = 1\n\ndef get_context_data(self, **kwargs):\n       context = super(HistoryView, self).get_context_data(**kwargs)\n       context.update({\n           \'geohazards\': GeoHazard.objects.all(),\n           \'assessments\': Assessment.objects.all()\n          })\n\n       return context\n
Run Code Online (Sandbox Code Playgroud)\n

所以我尝试了一种不同的方法;现在,通过使用 get_context_data 覆盖“context”,在我的“ListView”中传递 3 个模型。在这种方法中,所有内联字段都显示在我的模板template-views2-A.png中,但这一次它引发了一个新问题,即使所有内联字段都显示在模板中,但它并不与其关联的父字段一起显示。现在,当在分页按钮中选择新页面时,父字段会更改template-views2-B.png \n但内联字段保持不变。

\n

此外,我在更新“context”字典时还尝试了“GeoHazard.objects.filter(history_id=1)”,但这不是解决方案,因为这只能从具有特定值的父字段中获取内联字段。 ID。然后我尝试使用自定义模板标签,django自定义模板标签,但它不起作用。

\n
\n

(template.html)\n这是我的模板顺便说一句:

\n

\r\n
\r\n
from django.db import models\n\nclass History(models.Model):\n   BARANGAY = (\n     (\'Alegria\',\'Alegria\'),\n     (\'Bagacay\',\'Bagacay\'),\n     (\'Baluntay\',\'Baluntay\'),\n     (\'Datal Anggas\',\'Datal Anggas\'),\n     (\'Domolok\',\'Domolok\'),\n     (\'Kawas\',\'Kawas\'),\n     (\'Ladol\',\'Ladol\'),\n     (\'Maribulan\',\'Maribulan\'),\n     (\'Pag-Asa\',\'Pag-Asa\'),\n     (\'Paraiso\',\'Paraiso\'),\n     (\'Poblacion\',\'Poblacion\'),\n     (\'Spring\',\'Spring\'),\n     (\'Tokawal\',\'Tokawal\')\n   )\n  barangay_name = models.CharField(max_length=100,choices=BARANGAY,default=\'Alegria\')\n  barangay_img = models.ImageField(upload_to=\'history_imgs\',blank=True)\n  barangay_info = models.TextField()\n\nclass GeoHazard(models.Model):\n  history = models.ForeignKey(History,related_name=\'geohazards\',on_delete=models.CASCADE)\n  geohazard_img = models.ImageField(upload_to=\'history_imgs\',blank=True)\n  date_published = models.CharField(max_length=100, null=True)\n  geohazard_info = models.TextField()\n\nclass Assessment(models.Model):\n   RATINGS = (\n      (\'HIGH\',\'HIGH\'),\n      (\'HIGH (Mitigated)\',\'HIGH (Mitigated)\'),\n      (\'MODERATE\',\'MODERATE\'),\n      (\'MODERATE (Mitigated)\',\'MODERATE (Mitigated)\'),\n      (\'LOW\',\'LOW\'),\n      (\'UNKNOWN\',\'UNKNOWN\'),\n   )\n\n   history = models.ForeignKey(History,related_name=\'assessment\',on_delete=models.CASCADE)\n   purok_name = models.CharField(max_length=50)\n   purok_coordinates = models.CharField(max_length=100,default=\'unknown\')\n   flood_rating = models.CharField(max_length=100,choices=RATINGS,default=\'UNKNOWN\')\n   landslide_rating = models.CharField(max_length=100,choices=RATINGS,default=\'UNKNOWN\')\n
Run Code Online (Sandbox Code Playgroud)\r\n
\r\n
\r\n

\n

template-with-labels.png \n在这张图片中,我标记了我尝试在模板中显示的每个字段。

\n

多年来一直致力于此,并期待任何可以提供帮助的人。非常渴望找到解决方案,项目\xe2\x80\x99 的截止日期就在我们家门口。提前致谢!

\n

Ber*_*ant 1

您应该能够通过以下方式访问相关对象GeoHazardAssessment对象related_name

{% for history in histories %}
    {{ history.barangay_name}
    {# other history information #}

    {% for hazard in history.geohazards.all %}
        {{ hazard.geohazard_info }}
        {# other hazard information #}
    {% endfor %}

   {% for assessment in history.assessment.all %}
        {{ assessment.purok_name }}
        {# other assessment information #}
    {% endfor %}
{% endfor %}
Run Code Online (Sandbox Code Playgroud)

访问由 定义的属性related_name将返回 a 的实例,该实例RelatedManager具有类似的方法(与模型上all()相同)。objects

请注意,要使其工作,您不需要在上下文中添加任何其他内容,但从性能角度来看,使用其他方式可能有意义,prefetch_related()否则为每个History实例执行附加查询来获取相关对象。

{% for history in histories %}
    {{ history.barangay_name}
    {# other history information #}

    {% for hazard in history.geohazards.all %}
        {{ hazard.geohazard_info }}
        {# other hazard information #}
    {% endfor %}

   {% for assessment in history.assessment.all %}
        {{ assessment.purok_name }}
        {# other assessment information #}
    {% endfor %}
{% endfor %}
Run Code Online (Sandbox Code Playgroud)