Вопрос:
У меня есть требование создать форму опроса. У разных типов пользователей будет задан различный набор вопросов для ответа в опросе.
models.py
from django.contrib.auth.models import Group, User from django.db import models ANSWER_CHOICES = ( (‘0’, ‘No’), (‘1’, ‘Yes’) ) class Survey(models.Model): name = models.CharField(max_length=100) group = models.ForeignKey(Group) def __str__(self): return self.name class Feature(models.Model): name = models.CharField(max_length=150) survey = models.ForeignKey(Survey) def __str__(self): return self.name class Rating(models.Model): rating = models.IntegerField(choices=ANSWER_CHOICES) feature = models.ForeignKey(Feature) rating_for = models.ForeignKey(User, related_name=’rated_user’) rating_by = models.ForeignKey(User, related_name=’rated_by’) def __str__(self): return str.format(«%s — %s», self.feature, self.rating)
Ответ (рейтинг) для каждого вопроса (функции) – это либо да, либо нет. Когда пользователь отправляет форму, она сохраняет ответы в таблице рейтинга.
Каков способ достижения этого django?
Спасибо
forms.py
from django import forms from django.forms import modelformset_factory, TextInput from survey.models import Rating, Feature class FeatureForm(forms.ModelForm): class Meta: model = Feature class RatingForm(forms.ModelForm): class Meta: model = Rating FeatureFormSetBase = modelformset_factory(Feature, extra=0, widgets={‘name’: TextInput(attrs={‘readonly’: True, })} ) class FeatureFormSet(FeatureFormSetBase): def add_fields(self, form, index): super(FeatureFormSet, self).add_fields(form, index) form.fields[‘is_checked’] = forms.BooleanField(required=False)
survey.html
<form action=».» method=»post» accept-charset=»utf-8″> <ul class=»list-group»> {% for form in formset.forms %} <li class=»list-group-item»> <div class=»hidden»> {{ form.survey }}</div> <span> {{ form.name }} </span> <span> {{ form.id }} </span> <span> {{ form.is_checked }} </span> </li> {% endfor %} </ul> <p> {{ formset.management_form }} {% csrf_token %} <button type=»submit» name=»action» value=»save» class=»btn btn-success»>SAVE</button> </p> </form>
Что у меня есть код, и он работает сейчас, но я не уверен, что его лучший способ решить эту проблему? У меня есть много кода в views.py для анализа данных сообщения… есть ли более чистый способ достичь этого?
view.py
def questionnaire(request): q = Feature.objects.filter(survey__group=request.user.groups.all()[0]).select_related(‘survey’) if request.method == ‘POST’: action = request.POST.get(‘action’) formset = FeatureFormSet(request.POST, queryset=q) if formset.is_valid(): # iterate over all forms in the formset for form in formset.forms: if action == u’save’: answer = form.cleaned_data.get(‘is_checked’) print(«Saving answer…») rating = Rating() rating.rating = answer rating.feature = form.cleaned_data.get(‘id’) rating.rating_for = request.user rating.rating_by = request.user rating.save() redirect(‘useraccount_dashboard’) else: formset = FeatureFormSet(queryset=q) return render_to_response(‘account_survey.html’, {‘formset’: formset}, context_instance=RequestContext(request))
ОБНОВЛЕНО views.py
def questionnaire(request, instance_id): try: instance = SurveyInstance.objects.get(pk=instance_id, completed=False) except SurveyInstance.DoesNotExist: raise Http404 if instance.rating_by != request.user: return HttpResponse(‘Unauthorized’, status=401) q = Feature.objects.filter(survey=instance.survey) if request.method == ‘POST’: action = request.POST.get(‘action’) formset = FeatureFormSet(request.POST, queryset=q) if formset.is_valid(): # iterate over all forms in the formset for form in formset.forms: if action == u’save’: answer = form.cleaned_data.get(‘is_checked’) print(«Saving answer…») rating = Rating() rating.rating = answer rating.feature = form.cleaned_data.get(‘id’) rating.survey_instance = instance rating.save() instance.completed = True instance.save() messages.add_message(request, messages.INFO, ‘Thank you for your feedback.’) return redirect(‘useraccount_dashboard’) else: formset = FeatureFormSet(queryset=q) return render_to_response(‘account_survey.html’, {‘formset’: formset}, context_instance=RequestContext(request)) Ответ №1
Попробуйте использовать form.save() вместо создания объекта Rating, заполнив его и затем сохраните.