2017-04-12 10 views
0

공식 장고 투표 자습서는 간단하지만 POST 예외를 수동으로 처리하고 프런트 엔드를 하드 코드해야합니다. 양식을 사용하여 동일한 결과를 얻는 방법?양식을 사용하여 공식 Django Polls 예제를 구현하는 방법은 무엇입니까?

@csrf_protect 
def vote(request, question_id): 
    p = get_object_or_404(Question, pk=question_id) 
    if request.method == 'GET': 
     return render(request, 'polls/detail.html', { 
      'question': p, 
     }) 
    if request.method == 'POST': 
     try: 
      selected_choice = p.choice_set.get(pk=request.POST['choice']) 
     except (KeyError, Choice.DoesNotExist): 
      # Redisplay the question voting form. 
      return render(request, 'polls/detail.html', { 
       'question': p, 
       'error_message': "You didn't select a choice.", 
      }) 
     else: 
      selected_choice.votes += 1 
      selected_choice.save() 
      return HttpResponseRedirect(reverse('polls:results', args=(p.id,))) 



#urls.py 
url(r'^(?P<question_id>[0-9]+)/vote/$', views.vote, name='vote'), 


#models.py 
class Question(models.Model): 
    question_text = models.CharField(max_length=200) 
    pub_date = models.DateTimeField('date published') 

    def __str__(self): 
     return self.question_text 

    def was_published_recently(self): 
     return self.pub_date >= timezone.now() - datetime.timedelta(days=1) 


class Choice(models.Model): 
    question = models.ForeignKey(Question) 
    choice_text = models.CharField(max_length=200) 
    votes = models.IntegerField(default=0) 

    def __str__(self): 
     return self.choice_text 



# polls/templates/polls/detail.html 
<h1>{{ question.question_text }}</h1> 

{% if error_message %}<p><strong>{{ error_message }}</strong></p>{% endif %} 

<form action="{% url 'polls:vote' question.id %}" method="post"> 
{% csrf_token %} 
{% for choice in question.choice_set.all %} 
    <input type="radio" name="choice" id="choice{{ forloop.counter }}" value="{{ choice.id }}" /> 
    <label for="choice{{ forloop.counter }}">{{ choice.choice_text }}</label><br /> 
{% endfor %} 
<input type="submit" value="Vote" /> 
</form> 

나는 수행하여 과정을 쉽게 할 :

if form.is_valid(): 
    ... 
    votes += 1 

{{ form }}이 Choice.DoesNotExist을 감지하고 기본적으로 오류 메시지를 렌더링 할 수있는 템플릿 {{ form }}.

답변

0
{##########################################} 
{## pollsForm/templates/pollsForm/detail.html#} 
{##########################################} 
{###pay attention to {{choice_forms}}###} 

<h1> {{ question.question_text }}</h1> 

<form action="{% url 'pollsForm:vote' question.id %}" method="post"> {% csrf_token %} 
    {{ choice_forms }} 
    <input type="submit" value="Vote" /> 
</form> 

{##########################################} 
{## pollsForm/templates/pollsForm/results.html#} 
{##########################################} 
{#This is optional page. This is from official tutorial##} 
<h1>{{ question.question_text }}</h1> 

<ul> 
{% for choice in question.choice_set.all %} 
    <li>{{ choice.choice_text }} -- {{ choice.votes }} vote{{ choice.votes|pluralize }}</li> 
{% endfor %} 
</ul> 

<a href="{% url 'pollsForm:vote' question.id %}">Vote again?</a> 




######################################## 
# pollsForm/models.py 
######################################## 

same 

######################################## 
# pollsForm/urls.py 
######################################## 

from django.conf.urls import url 

from . import views 

# namespace='pollsForm' 
# append the following line to the myproject/urls.py 
#  url(r'^pollsForm/', include('pollsForm.urls', namespace='pollsForm')), 

urlpatterns = [ 
    url(r'^(?P<question_id>[0-9]+)/vote/$', views.vote, name='vote'), 
    url(r'^(?P<pk>[0-9]+)/results/$', views.ResultsView.as_view(), name='results'), 
] 

######################################## 
# pollsForm/views.py 
######################################## 

from django.shortcuts import get_object_or_404, render 
from django.http import HttpResponseRedirect 
from django.core.urlresolvers import reverse 
from django.views import generic 
from django.views.decorators.csrf import csrf_protect 
from .models import Choice, Question 
from django import forms 
from django.forms import widgets 
from .forms import ChoiceForm 

@csrf_protect 
def vote(request, question_id): 
    p = get_object_or_404(Question, pk=question_id) 
    c_set = Choice.objects.filter(question=question_id) 

    if request.method == 'GET': 
     cforms = ChoiceForm() 
     cforms.fields['choice_text'] = forms.ModelChoiceField(queryset=c_set, 
                   empty_label=None, 
                   widget=widgets.RadioSelect) 
     variables = { 
      'choice_forms': cforms, 
      'question': p, 
     } 
     return render(
      request, 
      'pollsForm/detail.html', 
      variables, 
     ) 

    if request.method == 'POST': 
     form = ChoiceForm(request.POST) 
     if form.is_valid(): 
      pk = form.cleaned_data['choice_text'] 
      selected_choice = p.choice_set.get(pk=pk) 
      selected_choice.votes += 1 
      selected_choice.save() 
      return HttpResponseRedirect(reverse('pollsForm:results', args=(p.id,))) 

     if not form.is_valid(): 
      # change input char to radio 
      form.fields['choice_text'] = forms.ModelChoiceField(queryset=c_set, 
                   empty_label=None, 
                   widget=widgets.RadioSelect) 
      variables = { 
       'choice_forms' : form, 
       'question': p, 
      } 
      return render(
       request, 
       'pollsForm/detail.html', 
       variables, 
      ) 

# optional 
class ResultsView(generic.DetailView): 
    model = Question 
    template_name = 'pollsForm/results.html' 

이 백엔드로 라디오 양식을 처리하는 방법을 예입니다.

이것은 공식 설문 조사 앱과 동일한 pollsForm 앱이지만 프런트 엔드를 어지럽히 기보다는 양식을 사용합니다. 프런트 엔드에 {{choice_forms}}을 생성합니다.

1

먼저 양식을 정의해야합니다. Convention은 forms.py에서이를 수행하는 것입니다. 폼은 "폼"으로부터 상속받은 클래스입니다. 폼을 직접 정의해야하는 forms.Form 또는 모델을 기반으로 폼을 생성하는 forms.ModelForm 중 하나를 사용할 수 있습니다.

질문 모델은 당신이 시작하는 데,하지만 당신이 더 많은 입력이 읽어야 위해 내가 예를 제공합니다

: 당신은 "무대 마술 뒤에"당신이로 볼 수 찾고 있다면 https://docs.djangoproject.com/en/1.10/topics/forms/

아, 그리고 클래스 기반보기. 그들은 당신을 위해 많은 것을 처리합니다. 그들은 약간의 사용자 정의 복잡하지만, 주제에 대한 몇 가지 YouTube turorials가 있습니다. forms.ModelForm에 대한

예 :

class QuestionForm(forms.ModelForm): 

class Meta: 
    # Define the model here: 
    model = Question 
    # Define the fields that you want to show up. Alternatively you can use "exclude", in which you specify the fields that you dont want to show up. 
    fields = [ 
      "question_text", 
      "pub_date", 
    ] 
    # You can use labels to define custom labels. 
    labels = { 
      "question_text": "Question Headline", 
      } 

    # Specify the widgets you want to use, if they differ from the standard widgets defined by the modelField. This is especialy usefull for ForeignKeys. 
    #widgets = { 
    # 'question': forms.HiddenInput, 
    #}