美文网首页
【Django】入门实践指南之模板复用&表单处理|第6篇

【Django】入门实践指南之模板复用&表单处理|第6篇

作者: 繁华落尽丶lee | 来源:发表于2018-05-08 10:21 被阅读30次

    课程:Django入门项目 - 论坛系统
    打卡时间:2018.5.8

    目录

    【Django】入门实践指南之环境搭建|第0篇
    【Django】入门实践指南之系统设计|第1篇
    【Django】入门实践指南之模型设计|第2篇
    【Django】入门实践指南之模板引擎|第3篇
    【Django】入门实践指南之测试&静态文件配置|第4篇
    【Django】入门实践指南之Admin&URL分发|第5篇
    【Django】入门实践指南之模板复用&表单处理|第6篇

    前言

    本篇学习模板复用和表单的一些知识,这篇文章比较长。耐心读完会有收获的。

    一、模板复用

    之前我们创建的两个home.htmltopic.html。他们之间存在一些相同的内容,如果单独创建文件少还可以,如果有几十个页面甚至上百个页面,维护起来就相当麻烦了。这是就需要复用技术。

    通过编写一个母模板,包含页面所共有的内容。其他模板继承自母模板。

    templates中创建名为base.html的文件。

    {% load static %}<!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>{% block title %}Django Boards {% endblock %}</title>
        <link rel="stylesheet" href="{% static 'css/bootstrap.min.css' %}">
    </head>
    <body>
        <div class="container">
            <ol class="breadcrumb my-4">
                {% block breadcrumb %}
                {% endblock %}
            </ol>
            {% block content %}
            {% endblock %}
        </div>
    </body>
    </html>
    

    以上就是母版页,其他模板都需要继承该模板。模板中{% block %}标签。它用于在模板中保留一个空间,子模板可以在其中插入代码和HTML。

    例如:{% block title %}是接收title的,母版中给出了默认值。

    下面重写之前的两个模板: home.htmltopic.html

    {#继承自base.html#}
    {% extends 'base.html' %}
    
    {#添加头部导航标签#}
    {% block breadcrumb %}
        <li class="breadcrumb-item active">Boards</li>
    {% endblock %}
    
    {#页面内容#}
    {% block content %}
    <table class="table">
                <thead class="">
                <tr>
                    <th>Board</th>
                    <th>Posts</th>
                    <th>Topics</th>
                    <th>Last Post</th>
                </tr>
                </thead>
                <tbody>
                    {% for board in boards %}
                        <tr>
                            <td>
    {#                            进入board_topics传递参数pk #}
                                <a href="{% url 'board_topics' board.pk%}">{{ board.name }}</a>
                                <small class="text-muted d-block">{{ board.desc }}</small>
                            </td>
                            <td class="align-middle">0</td>
                            <td class="align-middle">0</td>
                            <td></td>
                        </tr>
                    {% endfor %}
                </tbody>
            </table>
    
    {% endblock %}
    

    topic界面

    {% extends 'base.html' %}
    
    {% block title %}
        {{ board.name }} - {{ block.super }}
    {% endblock %}
    
    {% block breadcrumb %}
        <li class="breadcrumb-item"><a href="{% url 'home' %}">Boards</a></li>
        <li class="breadcrumb-item active">{{ board.name }}</li>
    {% endblock %}
    
    {% block content %}
    
    {% endblock %}
    

    修改完成后,可以验证一下是否存在错误。

    执行python manage.py test

    二、表单处理

    表单用来处理用户的输入。下面看一个例子吧!

    新建一个路由,命名为new_topic:

    {% extends 'base.html' %}
    
    {% block title %}
    Start a New Topic
    {% endblock %}
    
    {% block breadcrumb %}
        <li class="breadcrumb-item"><a href="{% url 'home' %}">Boards</a></li>
        <li class="breadcrumb-item"><a href="{% url 'board_topics' board.pk %}">{{ board.name }}</a></li>
        <li class="breadcrumb-item active">New topic</li>
    {% endblock %}
    
    {% block content %}
    
    {% endblock %}
    

    new_topic进行测试

    class NewTopicTests(TestCase):
        def setUp(self):
            Board.objects.create(name='Django', desc='Django board')
    
        def test_new_topic_view_success_status_code(self):
            url = reverse('new_topic', kwargs={'pk': 1})
            response = self.client.get(url)
            self.assertEquals(response.status_code, 200)
    
        def test_new_topic_view_not_found_status_code(self):
            url = reverse('new_topic',kwargs={'pk': 99})
            response = self.client.get(url)
            self.assertEquals(response.status_code, 404)
    
        def test_new_topic_url_resolves_new_topic_view(self):
            view = resolve('/boards/1/new/')
            self.assertEquals(view.func, new_topic)
    
        def test_new_topic_view_contains_link_back_top_board_topics_view(self):
            new_topic_url = reverse('new_topic', kwargs={'pk': 1})
            board_topic_url = reverse('board_topics', kwargs={'pk': 1})
            response = self.client.get(new_topic_url)
             self.assertContains(response, 'href="{}"'.format(board_topic_url))
    

    setUp:创建一个测试中使用的 Board 实例
    test_new_topic_view_success_status_code:检查发给 view 的请求是否成功
    test_new_topic_view_not_found_status_code:检查当 Board 不存在时 view 是否会抛出一个 404 的错误
    test_new_topic_url_resolves_new_topic_view:检查是否正在使用正确的 view
    test_new_topic_view_contains_link_back_to_board_topics_view:确保导航能回到 topics 的列表

    运行python manage.py test,查看测试结果。

    new_topic添加表单。

    
    {% block content %}
        <form method="post">
        {% csrf_token %}
        <div class="form-group">
            <label for="id_subject" class="">Subject</label>
            <input type="text" class="form-control" id="id_subject" name="subject">
        </div>
        <div class="form-group">
            <label for="id_message" class="">Message</label>
            <textarea name="message" id="id_message" rows="5" class="form-control"></textarea>
        </div>
        </form>
    {% endblock %}
    

    csrf_token模板标签,它是与其他表单数据一起提交的隐藏字段。

    获取数据用户输入的数据。

    def new_topic(request, pk):
        board = get_object_or_404(Board, pk=pk)
    
        if request.method == 'POST':
            subject = request.POST['subject']
            message = request.POST['message']
            user = User.objects.first() # 临时登陆账户
    
            topic = Topic.objects.create(
                subject = subject,
                board = board,
                starter = user
            )
            post = Post.objects.create(
                message = message,
                topic = topic,
                created_by = user
            )
            return redirect('board_topics', pk=board.pk) # 重定向到topic页
        return render(request, 'new_topic.html', {'board': board})
    

    参考:表单处理
    由于代码较多,这里不粘贴代码。

    三、创建表单的正确方式

    Forms API创建表单,在django.forms模块中。两种表单类型:
    forms.Form: 通用表单实现
    forms.ModelFrom:Form的子类,它与Model相关联。

    boards/forms.py

    from django import forms
    from .models import Topic
    
    class NewTopicForm(forms.ModelForm):
        message = forms.CharField(widget=forms.Textarea(), max_length=4000)
    
        class Meta:
            model = Topic
            fields = ['subject', 'message']
    

    这是我们的第一个 form。它是一个与 Topic model 相关联的 ModelForm。Meta 类里面 fields 列表中的 subject 引用 Topic 类中的 subject field(字段)。现在注意到我们定义了一个叫做 message 的额外字段。它用来引用 Post 中我们想要保存的 message。

    四、小结

    本篇学习表单的基本用法,Form API的使用方法。由代码较多没有整理,请查看:表单处理

    相关文章

      网友评论

          本文标题:【Django】入门实践指南之模板复用&表单处理|第6篇

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