【问题标题】:How to combine multiple querysets in django [duplicate]如何在 django 中组合多个查询集 [重复]
【发布时间】:2021-08-05 21:23:51
【问题描述】:

假设有一个事件模型,每个事件都有一个客户和一个顾问。此外,一位顾问可以有多个事件。每个事件都有许多不同的文档。我正在尝试在顾问登录时显示事件列表,并且在该列表中应该显示它们各自的文档。

模型.py:

class Client_Profile(models.Model):
    user_id = models.OneToOneField(User, primary_key=True, on_delete=models.CASCADE)  # Field name made lowercase.
    first_name = models.CharField(db_column='First_name', max_length=50)  # Field name made lowercase.
    last_name = models.CharField(db_column='Last_name', max_length=50)  # Field name made lowercase.
    phone_number = models.PositiveIntegerField(db_column='Phone_number', max_length=10)  # Field name made lowercase.
    # role_id = models.ForeignKey(Role, on_delete=models.CASCADE)

    def __str__(self):
        return self.first_name


class Consultant_Profile(models.Model):
    user_id = models.OneToOneField(User, primary_key=True, on_delete=models.CASCADE)  # Field name made lowercase.
    first_name = models.CharField(db_column='First_name', max_length=50)  # Field name made lowercase.
    last_name = models.CharField(db_column='Last_name', max_length=50)  # Field name made lowercase.
    phone_number = models.PositiveIntegerField(db_column='Phone_number', max_length=10)  # Field name made lowercase.
    # role_id = models.ForeignKey(Role, on_delete=models.CASCADE)

    def __str__(self):
        return self.first_name


class Event(models.Model):
    event_id = models.AutoField(db_column='event_id', primary_key=True)
    client_id = models.ForeignKey(Client_Profile, db_column='Client_ID', on_delete=models.CASCADE)  # Field name made lowercase.
    consultant_id = models.ForeignKey(Consultant_Profile, db_column='Consultant_ID', on_delete=models.CASCADE)  # Field name made lowercase.

    def __str__(self):
        return str(self.event_id)


class Document(models.Model):
    document_id = models.AutoField(db_column='document_id', primary_key=True)
    document_name = models.CharField(db_column='document_name', max_length=50, null=True, blank=True)  # Field name made lowercase.
    path = models.FileField(null=True, upload_to='files/')
    date_uploaded = models.DateTimeField(default=timezone.now, null=True, blank=True)
    event_id = models.ForeignKey(Event, db_column='Client_ID', on_delete=models.CASCADE)  # Field name made lowercase.

    def __str__(self):
        return self.document_name + ": " + str(self.path)  # this specifies how should instance of this class should be printed.

views.py

@login_required
def consultant_home(request):
    consultant_pr = Consultant_Profile.objects.get(user_id=request.user)
    event_id = Event.objects.filter(consultant_id=consultant_pr.pk)
    for id in event_id:
        doc = Document.objects.filter(event_id=id)
    context = {'id': event_id, 'doc': doc, 'consultant_pr': consultant_pr}
    return render(request, 'Consultant/consultant_documents.html', context)

文档.html

                    {% for eve in id %}
                    <p>Event id: {{ eve.event_id }}</p>
                        {% for dox in doc %}
                            <p>document name: {{ dox.document_name }}</p>
                            <p>path: <a href="/media/{{dox.path}}">{{ dox.path}} </a> </p>
                        {% endfor%}
                    {% endfor %}

【问题讨论】:

标签: python django


【解决方案1】:

您可以使用document_setDocument 的默认related_name,即附加_set 的小写模型名称)简单地循环来自Event 对象本身的相关Document 对象。您还可以使用prefetch_related [Django docs]优化查询的数量:

在你看来:

@login_required
def consultant_home(request):
    consultant_pr = Consultant_Profile.objects.get(user_id=request.user)
    events = Event.objects.filter(consultant_id=consultant_pr.pk).prefetch_related('document_set')
    context = {'events': event, 'consultant_pr': consultant_pr}
    return render(request, 'Consultant/consultant_documents.html', context)

在您的模板中:

{% for event in events %}
    <p>Event id: {{ event.event_id }}</p>
    {% for document in event.document_set.all %}
        <p>document name: {{ document.document_name }}</p>
        <!-- Use document.path.url instead of manually rendering its url -->
        <p>path: <a href="{{ document.path.url }}">{{ document.path }} </a></p>
    {% endfor%}
{% endfor %}

【讨论】:

  • 我试过仍然给出错误说“在事件对象上找不到'文档','文档'是 prefetch_related() 的无效参数”
  • @YASHJARIWALA 试试.prefetch_related('document_set')
  • 现在它只是显示事件 id 而不是事件的文档列表
  • 哦....现在完成了,谢谢
猜你喜欢
  • 2014-07-08
  • 2013-09-06
  • 1970-01-01
  • 2017-03-09
  • 2014-01-27
  • 2017-10-09
  • 2018-08-02
  • 2021-03-23
  • 2018-04-24
相关资源
最近更新 更多