продовжуючи підручник з опитувань Django, я хочу запис (я назвав це numChoices) у моделі опитування, який автоматично оновлюється кількістю варіантів, пов’язаних із цим опитуванням. Як я можу це зробити?
class Poll(models.Model):
question = models.CharField(max_length=200)
pub_date = models.DateTimeField("date published")
numChoices = models.IntegerField()
def __unicode__(self):
return self.question
def was_published_recently(self):
now=timezone.now()
return now-datetime.timedelta(days=1) <= self.pub_date < now
was_published_recently.admin_order_field = "pub_date"
was_published_recently.boolean = True
was_published_recently.short_description = "Published recently?"
class Choice(models.Model):
poll = models.ForeignKey(Poll)
choice_text = models.CharField(max_length=200)
votes = models.IntegerField(default=0)
def __unicode__(self):
return self.choice_text
Уточнення, ідеальним варіантом використання буде такий, що:
Якщо я просто хочу перерахувати всі опитування з кількістю варіантів, пов’язаних із кожним опитуванням, не потрібно буде запитувати таблицю вибору.
Але кожного разу, коли я додаю вибір, запис опитування, пов'язаний з цим вибором, буде оновлювати його кількість numChoices
Відповіді:
2 для відповіді № 1Ви цього не хочете. Просто зробіть це властивістю моделі.
class Poll(models.Model):
...
@property
def numChoices(self):
return self.choice_set.count()
1 для відповіді № 2
Чи життєво важливо зберігати цю інформацію в моделі? Ви можете отримати підрахунок усіх пов’язаних об’єктів для моделі, просто виконавши:
count = poll_object.choice_set.count()
Django автоматично створює "_set" (у цьомуcase choice_set) для вас, коли у вас є зв’язок із зовнішнім ключем між двома моделями. За замовчуванням ім’я пов’язаної моделі буде скороченою версією назви моделі, тому пов’язане за замовчуванням ім’я моделі poll_choice буде «pollchoice_set». Ви можете замінити пов’язане ім’я, коли визначаєте поле FK, наприклад
class Choice(models.Model):
poll = models.ForeignKey(Poll, related_name="choices")
так що тепер ви зробите
poll_object.choices.count()
щоб отримати кількість пов'язаних об'єктів вибору.
1 для відповіді № 3
Як зазначалося в попередніх відповідях, ви можете простовикористовуйте @property, але це буде коштувати вам додаткового звернення до бази даних кожного разу, коли вам потрібен вибір. Наприклад, якщо ви хочете показати всі свої опитування на одній сторінці з такими варіантами підрахунку:
{% for poll in polls %}
{{ poll.question }} - Choises: {{ poll.numChoices }}
{% endfor %}
Він потрапить у базу даних для кожного опитування в циклі.Отже, у вас буде 1 + COUNT (Polls.objects.all ()) запитів для цієї простої операції. Ось чому ви можете зберегти підрахунок вибору у полі вашої моделі та додати інший метод для оновлення підрахунку вибору:
class Poll(models.Model):
choices_count = models.IntegerField() # To store num of choices.
def update_choices_count(self):
self.choices_count = self.choice_set.count()
self.save()
Як тільки ви створите своє опитування та додасте кілька варіантівВи можете запустити update_choices_count. Це не критично для адміністратора створювати деякі додаткові запити SQL під час редагування опитувань, але критично важливо для користувачів, щоб генерувати тонни додаткових звернень до бази даних лише для перегляду списку опитувань.