【发布时间】:2018-10-11 05:47:17
【问题描述】:
我有一个 Django 应用程序,它使用抽象基类(“答案”)并根据问题对象所需的 answer_type 创建不同的答案。 (这个项目开始于民意调查教程)。现在的问题是:
class Question(models.Model):
ANSWER_TYPE_CHOICES = (
('CH', 'Choice'),
('SA', 'Short Answer'),
('LA', 'Long Answer'),
('E3', 'Expert Judgement of Probabilities'),
('E4', 'Expert Judgment of Values'),
('BS', 'Brainstorms'),
('FB', 'Feedback'),
)
answer_type = models.CharField(max_length=2,
choices=ANSWER_TYPE_CHOICES,
default='SA')
question_text = models.CharField(max_length=200, default="enter a question here")
答案是:
class Answer(models.Model):
"""
Answer is an abstract base class which ensures that question and user are
always defined for every answer
"""
question = models.ForeignKey(Question, on_delete=models.CASCADE)
user = models.ForeignKey(User, on_delete=models.CASCADE, default=1)
class Meta:
abstract = True
ordering = ['user']
目前,我在 Answer 中有一个方法(覆盖 get_or_update_answer()),它带有特定于类型的指令来查看正确的表并收集或创建正确类型的对象。
@classmethod
def get_or_update_answer(self, user, question, submitted_value={}, pk_ans=None):
"""
this replaces get_or_update_answer with appropriate handling for all
different Answer types. This allows the views answer and page_view to get
or create answer objects for every question type calling this function.
"""
if question.answer_type == 'CH':
if not submitted_value:
# by default, select the top of a set of radio buttons
selected_choice = question.choice_set.first()
answer, _created = Vote.objects.get_or_create(
user=user,
question=question,
defaults={'choice': selected_choice})
else:
selected_choice = question.choice_set.get(pk=submitted_value)
answer = Vote.objects.get(user=user, question=question)
answer.choice = selected_choice
elif question.answer_type == 'SA':
if not submitted_value:
submitted_value = ""
answer, _created = Short_Answer.objects.get_or_create(
user=user,
question=question,
defaults={'short_answer': submitted_value})
else:
answer = Short_Answer.objects.get(
user=user,
question=question)
answer.short_answer = hashtag_cleaner(submitted_value['short_answer'])
etc... etc... (similar handling for five more types)
通过将所有这些逻辑放在“models.py”中,我可以为 page_view 加载任意数量问题的用户答案:
for question in page_question_list:
answers[question] = Answer.get_or_update_answer(user, question, submitted_value, pk_ans)
我相信有一种更 Pythonic 的方式来设计这段代码 - 我还没有学会使用它,但我不确定是什么。类似于接口的东西,这样每个对象类型都可以实现自己的 Answer.get_or_update_answer() 版本,Python 将使用适合该对象的版本。这将使扩展“models.py”更加整洁。
【问题讨论】:
标签: python django multiple-inheritance