2015-08-02 13 views
5

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)) 
+0

Ihr Code scheint in Ordnung zu sein. Was meinst du mit "Django Art, das zu erreichen"? – xyres

+1

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 –

Antwort

1

Versuchen Sie statt der Schaffung mit form.save() AKTUALISIERT die Rating Objekt, das Ausfüllen es Felder ist und Speichern dann.

+0

Mit der leichten Änderung, ich habe es tun, was ich wollte. –