如何从 Django 中基于 Class 的视图中的 2 个模型查询?

How to query from 2 Models in Class based views in django?

我有一个模型 Log 和另一个模型 Solutions,我正在使用 DetailView 来显示每个日志的详细信息

每条日志可以有多个解决方案。 Solutions 模型中有一个 log 字段是 Foreign KeyLog 模型..

现在,如果我想在日志详细信息下方显示该特定日志的所有解决方案,我该如何在同一个 html 模板中访问该特定日志的日志模型和解决方案

models.py:

class Log(models.Model):
    title = models.CharField(blank=False, max_length=500)
    content = models.TextField(blank=False)
    created = models.DateTimeField(auto_now_add=True)
    updated = models.DateTimeField(auto_now=True)
    slug = models.SlugField(max_length=50, null=False, unique=True)
    author = models.ForeignKey(User, on_delete=models.CASCADE,null=True, blank=True)
    image = models.ImageField(
        upload_to='images', blank=True)

    def save(self, *args, **kwargs):
        super().save()
        self.slug = self.slug or slugify(self.title + '-' + str(self.id))
        super().save(*args, **kwargs)

    class Meta:
        verbose_name = ("Log")
        verbose_name_plural = ("Logs")

    def __str__(self):
        return f"{self.title}"


    def get_absolute_url(self):
        return reverse("log-detail", kwargs={"question": self.slug})
    

class Solutions(models.Model):
    log = models.ForeignKey(
        Log, on_delete=models.CASCADE, blank=True, null=True)
    author = models.ForeignKey(User, on_delete=models.CASCADE,null=True, blank=True)
    solution = models.TextField(null=True)
    created = models.DateTimeField(auto_now_add=True)
    updated = models.DateTimeField(auto_now=True)
    slug = models.SlugField(max_length=50, null=False, blank=True)
    image = models.ImageField(
        upload_to='images', blank=True)

    def save(self, *args, **kwargs):
        self.slug = self.slug or slugify(self.solution)
        super().save(*args, **kwargs)

    class Meta:
        verbose_name = ("Solution")
        verbose_name_plural = ("Solutions")

    def __str__(self):
        return f"  {self.solution} "

views.py:

class LogDetailView(DetailView):
    model = Log
    slug_url_kwarg = 'question'
    slug_field = 'slug'

log_detail.html:

{% extends 'log/base.html' %}
{%load crispy_forms_tags %}
{% block content %}

<title>Error Logger - {{object.title}}</title>

<div class="main container mt-4 p-3 mb-4">
<img style='display:inline;' class='rounded-circle account-img' src="{{ object.author.profile.avatar.url }}" alt="">

  <h1 style='display:inline;'>
    <a href="#">{{ object.title }}</a>
  </h1>


  <p>Author: <a href="{% url 'profile' object.author   %}">{{ object.author }}</a></p>
  <p>Date and time of creation: {{ object.created }}</p>
  <span> Details </span>:
  <p class="big ml-4">{{ object.content }} <br />

  {% if object.image %}
  <img style="width: 20vw" class="mt-4" src="{{ object.image.url }}" alt="image" />
  {% else %} 
  {% endif %}

  </p>


</div>
<br />

<a
  class="btn btn-outline btn-info button-solution"
  href="#"
  >Add solution</a
>

您可以通过反向访问关系在模板中枚举这些,这通常是 <i>modelname</i>_set,除非您设置related_name=…。所以在这种情况下是 <b>solutions</b>_set:

{% for solution in object<b>.solutions_set.all</b> %}
    {{ solution }}
{% endfor %}

如果 ForeignKey 有一个 related_name=… [Django-doc],例如:

class Solutions(models.Model):
    log = models.ForeignKey(
        Log,
        on_delete=models.CASCADE,
        blank=True,
        null=True,
        <b>related_name='solutions'</b>
    )
    # …

然后我们访问它:

{% for solution in object<b>.solutions.all</b> %}
    {{ solution }}
{% endfor %}

Note: normally a Django model is given a singular name, so Solution instead of Solutions.