Различать c значений элементов, поступающих из двух наборов запросов в Django представлении / шаблоне - PullRequest
1 голос
/ 27 мая 2020

Мне нужно вывести список произведений, выполненных исполнителем. Одна и та же работа может выполняться несколько раз и в двух разных типах событий (например, модели performanceOfWork и Event).

class Work(models.Model):

    title = models.CharField(max_length=200) # max_length = required

class performanceOfWork(models.Model):

    solo_performer = models.ManyToManyField(Profile)
    performed = models.ForeignKey('Work', on_delete=models.CASCADE)

class Event(models.Model):

    solo_performer = models.ManyToManyField(Profile)
    repertoire = models.ManyToManyField(Work, blank=True)

В представлении мне удалось получить различные значения для каждого из двух моделей:

context['repertoire_from_works'] = performanceOfWork.objects.filter(solo_performer=self.get_object().id).values('performed__title').distinct()
context['repertoire_from_events'] = Event.objects.filter(solo_performer=self.get_object().id).values('repertoire__title').distinct()

Но тогда как мне справиться с одной и той же работой, выполняемой в обеих моделях? Я просто хочу вывести его один раз. Это очень неудобная попытка (которая не работает, потому что она проверяет оба значения в одном вложенном l oop):

      <ul>{% for work_works in repertoire_from_works.all %}
        {% for work_events in repertoire_from_events.all %}
          {% if work_works.performed__title == work_events.repertoire__title%}
            {% if forloop.first %}
            <li>{{ work_works.performed__title }}</li>
            {% endif %}

          {% else %}
          <li>{{ work_events.repertoire__title }}</li>
          <li>{{ work_works.performed__title }}</li>
          {% endif %}
        {% endfor %}
      {% endfor %}
      </ul>

1 Ответ

1 голос
/ 27 мая 2020

Да , вы можете запросить модель Work:

from django.db.models import Q

object = self.get_object()
context['works'] = <b>Work.</b>objects.filter(
    <b>Q(</b>performanceofwork__solo_performer=object.id<b>) |</b>
    <b>Q(</b>event__solo_performer=object.id<b>)</b>
).distinct()

Это даст вам коллекцию различных Work объектов, это часто лучше, поскольку Django модель «богаче» набора скалярных значений. Если две работы имеют одно и то же название, тогда будут возвращены разные работы.

Если вам действительно нужны только заголовки, тогда вы можете работать с:

from django.db.models import Q

object = self.get_object()
context['works'] = Work.objects.filter(
    <b>Q(</b>performanceofwork__solo_performer=object.id<b>) |</b>
    <b>Q(</b>event__solo_performer=object.id<b>)</b>
).values_list('title', flat=True).distinct()

Тогда вы получите повторяющийся строк (заголовков).

...