Bootstrap

Django入门教程(十五)数据库+模板继承+form表单练习

1、新建项目和app

2、实现效果
①list列表页
除了公共的导航栏外必须含有,其他内容自定义,但是需要将所有留言展示在首页上。
②添加页面
在这里插入图片描述
③修改页面
在这里插入图片描述

3、所需材料

①导航条模板与其css样式文件。
②留言板模板与其css样式文件。
③留言板模板与其相关的js文件。
以上所需文件可在:https://download.csdn.net/download/cf313995/10744034进行下载。

4、任务要求

①三个页面:
a、首页list:用来展示所有的留言;
b、添加页面add:添加留言;
c、修改页面update:更新留言;
②在app下新建urls.py文件,根目录下的urls.py:path(‘message/’, include())。
③模板中所有使用的url都是用name进行反向获取地址。

5、思路分析
(1)三个页面都有公共的导航条,对于公共的导航条,如果我们每个页面都写一遍,也是可以的,只是会浪费时间以及造成大量代码的冗余。所以这时我们就可以考虑使用模板继承,实现代码的复用。对于add页面和update页面,两者都有公共的内容模板(唯一的区别在于update页面比add页面多个ID),所以我们也可以考虑模板继承实现。画了一个简陋的图(╹▽╹),帮助初学者理清思路。
在这里插入图片描述

(2)使用模板继承的话,这时就会涉及到谁作为父模板的问题,我这里仅提供两种思路。

①第一种思路是把nav.html作为父模板且做为list页面,在模板中预留block的代码块,然后add页面继承nav.html,再在nav.html预留的代码块中加入留言板的内容模板(也就是form表单部分),因为add页面和update页面略有不同,update页面比add页面多出一栏ID,那么我们可以在add页面的输入姓名处的部分上部再次预留block代码块,然后以add为父模板,update继承add.html,然后再在预留的代码块中加入ID的部分就实现了我们目标,且一级一级继承下来,代码越来越少。
②第二种思路就是建立一个base.html,把nav.html放入到base.html,同时预留一个代码块。然后再建立一个base_form.html,继承至base.html,然后在base.html预留的代码块中,添加留言板的内容模板( 这里的内容就是add和update抽象出来的公共的内容模板)。因为add页面和update页面略有不同,我们还需要在base_form.html中预留代码块,add直接继承base_form模板,update继承base_form模板后再在base_form.html预留的代码块中加入ID的input标签。如此也能实现我们的需求。

6、代码实现
这里采用第二种思路实现。
(1)、项目相关配置
①将nav.html以及add.html和update.html放入templates文件夹,且在templates文件夹中新建base_form.html。将nav.html更改为base.html。
②在项目根目录下新建static文件夹,同时在static文件夹下新建css文件夹和js文件夹,用于分类存放静态资源。
③在settings.py文件中加入STATICFILES_DIRS=[os.path.join(BASE_DIR,‘static’)],引如static文件夹搜索路径。
④在app下新建urls.py
(2)项目整体架构
在这里插入图片描述
(3)、编写app下的urls.py也就是message下的urls.py

from django.urls import path
from message import views

urlpatterns=[
    path('list/',views.list,name='index'),
    path('add/', views.add,name='add'),
    path('update/', views.update,name='update'),
]

在这里插入图片描述
(4)、配置和项目根目录同名的urls.py文件。

from django.contrib import admin
from django.urls import path,include

urlpatterns = [
    path('admin/', admin.site.urls),
    path('message/', include('message.urls')),
]

在这里插入图片描述
(5)、模板处理
①修改base.html,add.html和update.html三个木板的额静态资源文件引入的方式。
这里有两种方式:
1>按照路径一步一步引入。如:src="/static/js/jquery-3.3.1.min.js"
2>使用{% static ‘/css/bootstrap.min.css’ %}引入。这种方式需要在模板首部添加{% load static %}标签。
这里使用的是第一种方式,仅对list.html模板做示例,其它模板写法相同。
找到引入css或js文件的地方,修改引入路径为下图所示:
在这里插入图片描述
在这里插入图片描述
其他模板的修改与此相同,这里不再讲解。
②将base.html中的导航栏部分,也就是nav标签部分收起来,同时在下面加入block标签。
修改后base.html如图所示:
在这里插入图片描述
③修改base_form模板,使其继承至base.html。同时在base.html预留的接口中,将add.html和update.html公共的部分(form标签的部分)抽离出来,放入预留的block接口中。同时加入method的请求方法为post,并在form表单中加入{% csrf_token %}标签(post请求必选,否则会报403的错误)。action表示提交地址,不填写默认提交给当前地址。
在这里插入图片描述
由于update.html比add.html多出一个ID标签,所以点开form标签,删掉ID部分,预留一个block标签。
在这里插入图片描述
③对于add.html模板,直接继承base_form.html即可。
在这里插入图片描述
④对于update.html模板,继承base_form.html,再加入ID部分。
在这里插入图片描述
⑤处理list.html,继承至base.html,同时加入一些自定义的内容。
在这里插入图片描述
(6)、模板处理完毕,开始编写models.py
①定义一个留言Message类。
在这里插入图片描述

from django.db import models

# Create your models here.

class Message(models.Model):
    name=models.CharField(max_length=20)
    email=models.EmailField(max_length=50,null=True)
    address=models.CharField(max_length=100)
    # TextField()不限制内容长度
    message=models.TextField()

    class Meta:
        db_table='message'      #设置展示在数据中的表名,不设置的话默认是app.模型类的名称。

②、手机models.py文件的变化,并同步至数据库中。与之前稍有不同,这里使用pycharm内置的方法。找到Tools–>Run manage.py Task。
在这里插入图片描述
此时就会出现:
在这里插入图片描述
③输入makemigrations,然后回车
在这里插入图片描述
再输入migrate,然后回车。
在这里插入图片描述
④此时查看数据库,message表和我们定义的字段已经生成好了。
在这里插入图片描述

(7)、模板处理完了,models类写完了,就该编写业务逻辑了,也就是编写views.py了。
①对于list页面,在进入list页面时,如果数据库中有留言信息,则直接展现到页面中,没有的话,则不展示。

from django.shortcuts import render
from .models import Message
# Create your views here.
def list(request):
    return render(request,template_name='list.html',context={'message':Message.objects.all()}) 

在这里插入图片描述
同时,我们需要list.html中加入一个if判断,如果message这个QuerySet集合(即从数据库中查询的message表)有数据的话,就使用for循环遍历它,然后展示它。
在这里插入图片描述
②对于add.html,在进入add.html时有一个get请求,在填写完数据进行添加的时候,又是一个请求,此时这个请求既可以使用get请求的方式,也可以使用post请求的方式。这里使用的是post请求(因为前面修改模板时method的请求方式为post)。对于不同的请求,分别返回不同的数据。如果是进入页面的get请求,则直接渲染add.html模板即可。如果是提交数据的post请求,则获取表单的数据,然后添加至数据库中。

def add(request):
    if request.method=='GET':
        return render(request,template_name='add.html')
    elif request.method=='POST':
        #通过表单添加数据
        name=request.POST['name']
        email=request.POST['email']
        address=request.POST['address']
        message=request.POST['message']
        Message.objects.create(name=name,email=email,address=address,message=message)
        return render(request, template_name='add.html',context={'result':'数据添加成功'})

在这里插入图片描述
紧接着修改add.html模板继承的base_form.html文件,加入一个if判断,如果有result传入,则展示结果到页面中。
在这里插入图片描述
③对于update.html,其实现逻辑基本和add.html思路相同。在进入update.html时有一个get请求,在填写完数据进行修改的时候,又是一个请求,此时这个请求既可以使用get请求的方式,也可以使用post请求的方式。这里使用的是post请求。对于不同的请求,分别返回不同的数据。如果是进入页面的get请求,则直接渲染update.html模板即可。如果是提交数据的post请求,则先查询该ID是否存在,存在的话再获取表单的数据,然后更新至数据库。不存在的话则直接返回ID不存在或用户不存在的信息。

def update(request):
    if request.method == 'GET':
        return render(request, template_name='update.html')
    elif request.method == 'POST':
        m_id=request.POST['id']
        try:
            m=Message.objects.get(id=m_id)
            m.name=request.POST['name']
            m.email = request.POST['email']
            m.address = request.POST['address']
            m.message = request.POST['message']
            m.save()
            return render(request, template_name='update.html',context={'result':'数据修改成功'})
        except:
            return render(request, template_name='update.html', context={'result': '该用户不存在'})

在这里插入图片描述

(8)、运行访问
①URL地址为入口地址message+具体地址。即127.0.0.1:8000/message/list/
在这里插入图片描述
②add页面也实现成功,只不过缺憾的是继承的是add和update共有的form部分,所以这个修改没有变成添加,解决方案就是再渲染这个模板时,可以再传入一个变量,将其放置在button的位置。这里我就不实现了,仅说下解决思路。
在这里插入图片描述
③添加数据
在这里插入图片描述
在这里插入图片描述
查看数据库中的表记录,已经成功添加。
在这里插入图片描述
④修改数据
在这里插入图片描述
在这里插入图片描述
发现修改成功
在这里插入图片描述

查看数据库表记录,同样修改成功。
在这里插入图片描述

到此,数据库+模板继承+form表单的练习就到此结束。
在这里插入图片描述

;