Ich habe eine Anforderung, ein Umfrageformular zu erstellen. Verschiedene Arten von Benutzern haben unterschiedliche Fragen, die in der Umfrage beantwortet werden müssen.Wie verwende ich django formsets, um eine Umfrage-App mit Fragen und Antworten zu erstellen?
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)
Die Antwort (Rating) für jede Frage (Funktion) ist entweder ein Ja oder Nein von Radio-Buttons darstellen. Sobald der Benutzer das Formular abschickt, speichert er die Antworten in der Bewertungstabelle.
Was ist der Django-Weg, um dies zu erreichen?
Dank
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>
, dass der Code ist ich habe und es funktioniert jetzt, aber ich bin nicht sicher, ob seine besten Weg, um dieses Problem zu lösen? Ich habe viel Code in views.py, um die Postdaten zu analysieren ... gibt es einen saubereren Weg, dies zu erreichen?
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))
Ihr Code scheint in Ordnung zu sein. Was meinst du mit "Django Art, das zu erreichen"? – xyres
Für den Anfang haben Sie keinen Code Ihres 'views.py' gepostet, der Ihre Sorge verursacht und zweitens - wenn Sie nach Optimierungstipps suchen; dann könnte es besser sein, es auf [codereview.stackexchange.com] (http://codereview.stackexchange.com) zu posten –