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
Source:stackexchange.com