Есть ли простой способ запроса фильтрации обратного отношения по значению, которое является значением по умолчанию, если объект еще не существует?Связанные объекты или по умолчанию
Позвольте мне подробнее остановиться на примере.
У меня есть следующие основные модели модели:
class Delegation(models.Model):
name = models.CharField(unique=True,max_length=4)
country = models.CharField(unique=True,max_length=100)
members = models.ManyToManyField(User, blank=True)
class Exam(models.Model):
name = models.CharField(max_length=100, unique=True)
active = models.BooleanField(default=True)
Теперь мне нужно хранить информацию о каких-то действий, в основном, если действие еще продолжается или завершена (представлен). По этой причине я использую модель, которая ссылается на обе модели.
class ExamAction(models.Model):
OPEN = 'O'
SUBMITTED = 'S'
STATUS_CHOICES = ((OPEN, 'In progress'), (SUBMITTED, 'Submitted'))
TRANSLATION = 'T'
POINTS = 'P'
ACTION_CHOICES = ((TRANSLATION, 'Translation submission'), (POINTS, 'Points submission'))
exam = models.ForeignKey(Exam)
delegation = models.ForeignKey(Delegation)
action = models.CharField(max_length=2, choices=ACTION_CHOICES)
status = models.CharField(max_length=1, choices=STATUS_CHOICES, default=OPEN)
timestamp = models.DateTimeField(auto_now=True)
class Meta:
unique_together = (('exam', 'delegation', 'action'),)
Моя проблема заключается в том, что запросы становятся в настоящее время довольно сложный, потому что (на данный момент) я предполагаю, что действие еще не могли быть перечислены в БД, для которой я принял бы значение по умолчанию ExamAction.OPEN
.
Для конкретного примера, это то, что я использую в данный момент запросить список экзаменов, которые все еще открыты для делегации:
exams_open = Exam.objects.filter((Q(examaction__delegation=delegation) & Q(examaction__action=ExamAction.TRANSLATION) & Q(examaction__status=ExamAction.OPEN))
| Q(examaction__isnull=True), active=True,)
Я считаю, что выше запрос тоже неправильно, потому что он должен вернуть объект Exam
, если нет ExamAction
с action=TRANSLATION
и delegation=delegation
, но это не будет, если другое действие уже сохранено (с любым значением).
Я уверен, что я не первый, столкнувшийся с этой проблемой дизайна, и я думаю, что должна существовать гораздо более простая реализация. Но что?
То, что я в настоящее время рассматриваю это:
ExamAction.objects.get_or_create()
- Задача 1: это не работает на нескольких матчах, то есть запрос прибудет должен быть уникальным
- Задача 2: это не нравится создавать объекты в запросе GET.
- Сгенерировать все возможные
ExamAction
при создании новогоExam
объекта. Это означало бы зацикливание, хотя все делегации.- Что делать, если делегация добавляется после сдачи экзамена?
- Есть ли отношения ManyToMany с
through=ExamAction
help в этой ситуации? Я так не думаю, потому что я все равно должен запрашивать у ExamAction желаемое (по умолчанию) значение или еще не существующее. - Полная редизайн? Я открыт для возможных идей!
Большое спасибо.
Спасибо за отзыв. Запрос в Менеджере действительно намного более изящный, и он не настолько уродлив, чтобы поддерживать, как я, в начале. –
Я попытался преследовать бит 2. Поскольку в конечном итоге у меня будет большая квадратичная база данных, я могу просто создать все записи в начале и избежать создания в запросах GET, я использовал сигналы post_save для обеих делегаций и экзамен. –
Обратите внимание, что я нашел проблему в запрошенном вами запросе. Я опубликовал, как я исправил и какую-то многословную отладку. –