django2.0入门教程第三节

作者: 闲睡猫 | 来源:发表于2018-01-01 09:39 被阅读1601次

    继上篇django2.0入门教程第二节,介绍了对django2.0模型类models的操作,本篇主要讲视图views和模板template

    django的视图用于处理url请求,并将响应的数据传递到模板,最终浏览器将模板数据进行渲染显示,用户就得到了想要的结果

    作为一个简易的投票系统, 除了index(主页), 还需要detail(详情页), results(结果页), vote(投票页) 这些视图。

    增加视图:polls/views.py

    #_*_coding:utf8_*_
    from django.shortcuts import HttpResponse
    def index(request):
        return HttpResponse("你好,欢迎来到投票系统的主页")
    
    def detail(request, question_id):
        return HttpResponse('你正在查看问题%s' % question_id)
    
    def results(request, question_id):
        response = '你正在查看问题%s的结果'
        return HttpResponse(response % question_id)
    
    def vote(request, question_id):
        return HttpResponse('你正在给问题%s投票' % question_id)
    

    配置url:polls/urls.py

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

    url访问:

    http://127.0.0.1:8000/polls/

    你好,欢迎来到投票系统的主页
    

    http://127.0.0.1:8000/polls/1/

    你正在查看问题1
    

    http://127.0.0.1:8000/polls/1/results/

    你正在查看问题1的结果
    

    http://127.0.0.1:8000/polls/1/vote/

    你正在给问题1投票
    

    这样的视图内容过于简略粗糙, 在后台添加多一些数据,供后续调用:

    threequestion.png

    通过视图直接返回的数据,显示格式很单一,要想显示丰富的数据形式,就需要引用模板,用独立的模板文件来呈现内容。

    新增模板:polls/templates/polls/index.html

    {% if latest_question_list %}
        <ul>
        {% for question in latest_question_list %}
        <li><a href="/polls/{{question.id}}/">{{question.question_text}}</a></li>
        {% endfor %}
        </ul>    
    {% else %}
        <p>问题为空</p>
    {% endif %}
    

    修改视图: polls/views.py 传递变量给模板

    #_*_coding:utf8_*_
    from django.shortcuts import HttpResponse
    from django.template import loader
    from .models import Question
    def index(request):
        latest_question_list = Question.objects.order_by('-pub_date')[:5]
        template = loader.get_template('polls/index.html')
        context = {'latest_question_list': latest_question_list}
        return HttpResponse(template.render(context, request))
    

    访问:http://127.0.0.1:8000/polls/

    index.png

    使用便捷写法--render()函数:

    from django.shortcuts import render
    from .models import Question
    def index(request):
        latest_question_list = Question.objects.order_by('-pub_date')[:5]
        context = {'latest_question_list': latest_question_list}
        return render(request, 'polls/index.html', context)
    

    开发中,直接使用render()即可,尽可能精简代码

    详情页的展示:

    polls/views.py

    from django.http import Http404
    from django.shortcuts import render
    from .models import Question
    # ...
    def detail(request, question_id):
        try:
            question = Question.objects.get(pk=question_id)
        except Question.DoesNotExist:
            raise Http404('问题不存在')
        return render(request, 'polls/detail.html', {'question': question})
    

    新增详情页:polls/templates/polls/detail.html

    {{ question }}
    

    http://127.0.0.1:8000/polls/3/

    问题3
    

    访问不存在的问题id时,会报404

    http://127.0.0.1:8000/polls/4/

    404.png

    404页面抛出的便捷写法:get_object_or_404()

    polls/views.py

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

    详情页输出关联数据表:

    <h1>{{ question.question_text }}</h1>
    <ul>
        {% for choice in question.choice_set.all %}
        <li>{{ choice.choice_text }}</li>
        {% endfor %}
    </ul>
    

    将问题下有关联选项一并输出:

    foreign.png

    去掉url的硬编码格式

    原本index.html的url定义形式是这样的:

    <li><a href="/polls/{{question.id}}/">{{question.question_text}}</a></li>
    

    这种写法属于硬编码方式,并不好,因为一旦详情页的url改变,就要去改变相应的html文件,如果html文件有很多处都引用了,逐一排查需要耗费相当多时间。将url改成以下形式即可实现自动转换:

    <li><a href="{% url 'detail' question.id %}">{{question.question_text}}</a></li>
    

    修改url配置:

    将polls/urls.py的详情页url由:path('<int:question_id>/', views.detail, name='detail')改为:path('specifics/<int:question_id>/', views.detail, name='detail')

    此时,index.html的url会自动由 http://127.0.0.1:8000/polls/1/ 转为 http://127.0.0.1:8000/polls/specifics/1/

    url的命名空间

    现实项目中,一个django项目是会有多个应用的,为了将这些应用进行区分,需要使用命名空间

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

    将index.html的url生成代码加上命名空间:

    <li><a href="{% url 'polls:detail' question.id %}">{{question.question_text}}</a></li>
    

    源码下载

    相关源码包

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

    相关文章

      网友评论

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

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