Я разрабатываю программу обучения лексике с Django (немецкий-шведский).Модели Django: как вернуть значение по умолчанию в случае несуществующего отношения внешнего ключа?
Данные словаря приложения состоят из большого количества «лексических карт», каждая из которых содержит одно или несколько немецких слов или терминов, которые соответствуют одному или нескольким шведским терминам.
Обучение доступно только для зарегистрированных пользователей, так как приложение отслеживает производительность пользователя, сохраняя score
для каждой лексической карты.
Словарные карточки имеют уровень (базовый, продвинутый, экспертный) и любое количество присваиваемых им тэгов.
Когда зарегистрированный пользователь начинает обучение, приложение должно рассчитать средние баллы пользователя для каждого уровня и тегов, чтобы он мог сделать свой выбор.
Я решил эту проблему путем введения модели под названием CardByUser
, которая имеет score
и поле и ForeignKey
отношение к моделям User
и Card
. Теперь я могу использовать функцию агрегирования Django, вычисляя средние баллы.
Большой недостаток: это работает только при наличии экземпляра CardByUser
для каждого экземпляра карты, который в настоящее время существует в БД, даже если пользователь только обучил 100 карт. Мое текущее решение состоит в создании всех этих CardByUser
экземпляров при создании Card
и при регистрации пользователя. Это, конечно, довольно неопределенно как с точки зрения памяти базы данных, так и вычислительного времени (регистрация пользователя занимает довольно много времени).
И это кажется совершенно неэлегантным, какие ошибки мне больше всего нравятся.
Есть ли лучший способ сделать это?
Может быть, это можно сказать Django следующее при расчете среднего балла за Card
:
- Если
CardByUser
для данногоCard
и пользователя существует, использовать его счет. - Если
CardByUser
не существует, используется значение по умолчанию -> счет 0.
это может быть сделано? Если да, то как?
Редактировать: Уточнение Спасибо С.Лотту за первый ответ, но я думаю, что моя проблема немного сложнее. Мой плохой, я пытаюсь уточнить, используя какой-то фактический код из моих моделей.
class Card(models.Model):
entry_sv = models.CharField(max_length=200)
entry_de = models.CharField(max_length=200)
... more fields ...
class CardByUser(models.Model):
user = models.ForeignKey(User)
card = models.ForeignKey(Card, related_name="user_cards")
score = models.IntegerField(default=0)
... more fields ...
Это означает, что многие CardByUser
объекты связаны с одной Card
.
Сейчас, на мой взгляд код, мне нужно создать QuerySet из CardByUser
объектов, которые удовлетворяют следующим критериям:
tag
поле соответстующемCard
объекта содержит определенную строку (я теперь это не является оптимальным либо, но не в центре внимание мой вопроса ...)- пользователь текущего пользователя
Тогда я агрегированный баллы. Мой текущий код выглядит следующим образом (укороченный):
user_cards = CardByUser.objects.filter(user=current_user)
.filter(card__tags__contains=tag.name)
avg = user_cards_agg.aggregate(Avg('score'))['score__avg']
Если CardByUser
для текущего пользователя и Card
не существует, она просто не может быть включена в агрегации. Вот почему я создаю все эти CardByUser
s со счетом 0.
Так как я могу избавиться от них? Любые идеи были бы хорошы!
Если это только для части геттера, я бы использовал свойство() в качестве декоратора. –