django2.0入门教程第四节

作者: 闲睡猫 | 来源:发表于2018-01-05 17:34 被阅读2283次

    继上篇 django2.0入门教程第三节,介绍了django2.0的视图views和模板template, 本节介绍如何在前台进行投票。

    构建一个简单的表单提交页

    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 id="choice{{ forloop.counter }}" type="radio" name="choice" value="{{ choice.id }}">
        <label for="choice{{ forloop.counter }}">{{ choice.choice_text }}</label><br />
        {% endfor %}
        <br />
        <input type="submit" name="" id="" value="投票" />
    </form>
    

    代码解析:

    • form表单提交的url为{%url 'polls:vote' question.id %}, 即表示访问polls/views.py的vote方法,并携带问题id作为参数。

    • 将问题的相关选项遍历,以单选框显示

    • form表单用post方式提交数据

    配置url

    polls/urls.py

    path('<int:question_id>/vote/', views.vote, name='vote'),
    

    投票页面截图 http://127.0.0.1:8000/polls/1/

    vote.png

    视图层处理提交结果

    polls/views.py

    from django.shortcuts import render, get_object_or_404
    from django.http import HttpResponse, HttpResponseRedirect
    from django.urls import reverse
    from .models import Question, Choice
    # ...
    def vote(request, question_id):
        question = get_object_or_404(Question, pk=question_id)
        try:
            selected_choice = question.choice_set.get(pk=request.POST['choice'])
        except (KeyError, Choice.DoesNotExist):
            return render(request, 'polls/detail.html', {
                'question': question,
                'error_message': "必须选择一个选项",
            })
        else:
            selected_choice.votes += 1
            selected_choice.save()
            return HttpResponseRedirect(reverse('polls:results', args=(question.id,)))
    

    代码解析:

    • request.POST['choice']接收表单页面提交的数据

    • 将投票次数加1,并更新数据库

    显示投票结果

    polls/views.py

    from django.shortcuts import render, get_object_or_404
    # ...
    def results(request, question_id):
        question = get_object_or_404(Question, pk=question_id)
        return render(request, 'polls/results.html', {'question': question})
    

    results.html

    <h1>{{ question.question_text }}</h1>
    <ul>
    {% for choice in question.choice_set.all %}
    <li>{{ choice.choice_text }} -- {{choice.votes}}</li>
    {% endfor %}
    </ul>
    
    <a href="{% url 'polls:detail' question.id %}">再投一次?</a>
    

    提交结果页面 http://127.0.0.1:8000/polls/1/results/

    result.png

    优化url和view写法

    另一种写法:
    将主键id代替question_id

    polls/urls.py

    #_*_coding:utf8_*_
    from django.urls import path
    from . import views
    app_name = 'polls'
    urlpatterns = [
        path('', views.IndexView.as_view(), name='index'),
        path('<int:pk>/', views.DetailView.as_view(), name='detail'),
        path('<int:pk>/results/', views.ResultsView.as_view(), name='results'),
        path('<int:question_id>/vote/', views.vote, name='vote'),
    ]
    

    使用<pk>代替<question_id>会更加灵活,<pd>代表主键

    相应的视图也需要修改成另一种写法,vote方法保持原样,用于比较两种写法的不同

    polls/views.py

    #_*_coding:utf8_*_
    from django.shortcuts import render, get_object_or_404
    from django.http import HttpResponseRedirect
    from django.urls import reverse
    from django.views import generic 
    from .models import Question, Choice
    
    class IndexView(generic.ListView):
        template_name = 'polls/index.html'
        context_object_name = 'latest_question_list'
    
        def get_queryset(self):
            return Question.objects.order_by('-pub_date')[:5]
    
    class DetailView(generic.DetailView):
        model = Question
        template_name = 'polls/detail.html'
    
    class ResultsView(generic.DetailView):
        model = Question
        template_name = 'polls/results.html'
    
    def vote(request, question_id):
        # ...
    

    入门教程不会对代码进入深入的讲解,先大致了解其作用即可,后续再逐个模块进行解析

    源码下载

    相关源码包

    如果对django2.0教程感兴趣,请关注我的简书,持续更新中...

    相关文章

      网友评论

      • xiongcy:你好,我在写这段代码的时候报错:

        try:
        selected_choice = question.choice_set.get(pk=request.POST['choice'])
        except (KeyError, Choice.DoesNotExist):
        return render(request, 'polls/detail.html', {
        'question': question,
        'error_message': "必须选择一个选项",
        })

        Exception Value:
        exceptions must derive from BaseException

        请问大神知道这是怎么回事吗?
      • 1779a9f4cf10:你好,希望看到关于优化的url和view这种用法的详细教程,谢谢!
      • 剑灵之灵:继续啊,不要停!
      • 冰城老太____孙景芝:你是一个很专业的人,大赞!

      本文标题:django2.0入门教程第四节

      本文链接:https://www.haomeiwen.com/subject/zipsnxtx.html