[Answered ]-Rewrite form with django forms

2👍

After a lot of experimenting this was the solution:

#forms.py
class VoteForm(forms.ModelForm):
    choice = forms.ModelChoiceField(queryset=None, widget=forms.RadioSelect)

    class Meta:
        model = Question
        exclude = ('question_text', 'pub_date')

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.fields['choice'].error_messages = {
            'required': 'No choice selected.',
            'invalid_choice': 'Invalid choice selected.'
        }
        instance = getattr(self, 'instance', None)
        if instance:
            self.fields['choice'].queryset = instance.choice_set
#vote.html
{% load static %}
<link rel="stylesheet" type="text/css" href="{% static 'polls/css/style.css' %}" />
<h2>{{ question.question_text }}</h2>
{% if error_message %}<p><strong>{{ error_message }}</strong></p>{% endif %}
{% if voted %}
<p><strong>Already voted on this question.</strong><p>
{% else %}
<form action="{% url 'polls:vote' question.id %}" method="post">
{% csrf_token %}
{{ form.non_field_errors }}
<div class="fieldWrapper">
    {{ form.choice.errors }}
    {{ form.choice }}
</div>
<input type="submit" value="Vote" />
</form>
{% endif %}
<p><a href="{% url 'polls:results' question.id %}">View results?</a></p>
#views.py
class VoteView(generic.UpdateView):
template_name = 'polls/vote.html'
model = Question
form_class = VoteForm

def get_queryset(self):
    return Question.objects.filter(pub_date__lte=timezone.now()).exclude(choice__isnull=True)

def get_context_data(self, **kwargs):
    context = super().get_context_data(**kwargs)
    # Check duplicate vote cookie
    cookie = self.request.COOKIES.get(cookie_name)
    if has_voted(cookie, self.object.id):
        context['voted'] = True
    return context

def get_success_url(self):
    return reverse('polls:results', args=(self.object.id,))

def form_valid(self, form):
    choice = form.cleaned_data['choice']
    choice.votes = F('votes') + 1
    choice.save()
    redirect = super().form_valid(form)

    # Set duplicate vote cookie.
    cookie = self.request.COOKIES.get(cookie_name)
    half_year = timedelta(weeks=26)
    expires = datetime.utcnow() + half_year
    if cookie and re.match(cookie_pattern, cookie):
        redirect.set_cookie(cookie_name, "{}-{}".format(cookie, self.object.id), expires=expires)
    else:
        redirect.set_cookie(cookie_name, self.object.id, expires=expires)

    return redirect

Leave a comment