Я недавно вернулся к этой проблеме, заменил одну или двести строк кода на пять или десять и подумал, что однажды кому-нибудь будет полезно найти то, что я здесь сделал.
Есть несколько элементов проблемы, с которой я столкнулся: во-первых, многие типы ответов должны быть созданы, сохранены и извлечены при необходимости; во-вторых, дихотомия GET vs POST (и мое уникальное решение всегда создавать ответ, отправляя его в форму); в-третьих, некоторые типы имеют разную логику (мозговой штурм может иметь несколько ответов на пользователя, обратная связь даже не нуждается в ответе - если он создан для пользователя, он был представлен.) Эти элементы, вероятно, скрывают некоторую возможность удаления повторение, которое делает шаблон посетителя вполне подходящим.
Решение для элементов 1 и 2
Словарь кодов question.answer_type, который сопоставляется с соответствующим подклассом ответа, создается в views.py (поскольку его трудно разместить в models.py и разрешить зависимости):
# views.py:
ANSWER_CLASS_DICT = {
'CH': Vote,
'SA': Short_Answer,
'LA': Long_Answer,
'E3': EJ_three_field,
'E4': EJ_four_field,
'BS': Brainstorm,
'FB': FB,}
Тогда я могу получить класс ответа, который я хочу получить get_or_created для любого вопроса:
ANSWER_CLASS_DICT[question.answer_type]
Я передаю его в качестве параметра методу класса:
# models.py:
def get_or_update_answer(self, user, question, Cls, submitted_value=None, pk_ans=None):
if not submitted_value:
answer, _created = Cls.objects.get_or_create(user=user, question=question)
elif isinstance(submitted_value, dict):
answer, _created = Cls.objects.get_or_create(user=user, question=question)
for key, value in submitted_value.items():
setattr(answer, key, value)
else:
pass
Таким образом, те же шесть строк кода обрабатывают get_or_creating любой Ответ, когда submit_value = Нет (GET) или нет (submit_value).
Решение для элемента 3
Решением для третьего элемента было расширение модели, чтобы разделить как минимум три типа обработки для пользователей, повторно посещающих один и тот же вопрос:
«S» - одиночный, который позволяет им записывать только один ответ, пересматривать и исправлять ответ, но никогда не давать два разных ответа.
'T' - отслеживается, что позволяет им каждый раз обновлять свой ответ, но делает историю того, что их ответ был доступен (например, для исследователей).
'M' - множественное число, позволяющее ответить на один вопрос.
После всех этих изменений все еще исправляются ошибки, поэтому я не буду публиковать код.
Следующая функция: составные вопросы и шаблоны вопросов, чтобы люди могли использовать администратора для вывода на экран, чтобы сделать свои собственные типы ответов.