内容回顾:

补充反向解析
Html:{% url ‘别名’ 参数 %} Views:reverse(‘别名’,args=(参数,)) 模板渲染 变量 {{ 变量名 }}
逻辑相关 {% %} 过滤器:
{{ 变量|过滤器方法:’参数’ }} 标签:
{% for i in list%} for k,v in dict.items
{{ i }}
{% endfor %} {% if 条件 %} {%elif%} {%else%} {% endif %} 据点符 . 可以做深度查询 {% with 变量名=变量.属性.属性.. %}
{% with 变量.属性.属性.. as 变量名%} {% endwith %} 母板继承
先写一个母板,大家共用的地方
母板预留钩子:
{% block ‘名字’ %} 母板里面的可以被替换的内容
{%Endblock 名字%} 再写子页面 子页面里面第一行 {% extends ‘母板名称’ %}
{% block ‘名字’ %}
{{ block.super }}
子页面的内容 {%Endblock 名字%} Csrf_token : {% csrf_token %}

1.模板渲染组件

可以将常用的页面内容如导航条,页尾信息等组件保存在单独的文件中,然后在需要使用的地方,文件的任意位置按如下语法导入即可。

{% include 'navbar.html' %}

例如:有个如下的导航栏,nav.html

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
.c1{
background-color: red;
height: 40px;
}
</style>
</head>
<body> <div class="c1">
<div>
<a href="">xx</a>
<a href="">dd</a>
</div>
</div> </body>
</html>

嵌入导航栏的页面,test.html

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
{% include 'nav.html' %}
<h1>xxxxxxxxxx</h1>
</body>
</html>

from django.conf.urls import url
from django.contrib import admin
from app01 import views
urlpatterns = [
# url(r'^admin/', admin.site.urls),
url(r'^index/', views.index),
url(r'^user/', views.user),
url(r'^order/', views.order),
url(r'^zujian/', views.zujian),
]

urls.py

from django.shortcuts import render

# Create your views here.
def index(request):
return render(request,'index.html') def user(request):
return render(request,'usercenter.html') def order(request):
return render(request,'order.html') def zujian(request):
return render(request,'xiaomi.html')

views.py

<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta http-equiv="content-Type" charset="UTF-8">
<meta http-equiv="x-ua-compatible" content="IE=edge">
<meta name="viewport" content="width=device-width" ,initial-scale="">
<!--上边这个表示手机版的调整尺寸-->
<!--上述2个meta标签"必须"放在最前面,任何其他内容都必须跟随其后-->
<title>Title</title>
</head>
<body>
{% include 'zujian.html' %}
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
</ul>
</body>
</html>

xiaomi.html

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
.c1{
background-color: red;
height: 40px;
}
</style>
</head>
<body> <div class="c1">
<div>
<a href="">xx</a>
<a href="">dd</a>
</div>
</div> </body>
</html>

zujian.html

根据位置进行引入.

2.CBV和FBV=>dispatch方法

开发的两种模式:

FBV:(function base views)就是在视图里使用函数处理请求

CBV:(class base views) 就是在视图里使用类处理请求

  Python是一个面向对象的编程语言,如果只用函数来开发,有很多面向对象的优点就错失了(继承、封装、多态)。所以Django在后来加入了Class-Based-View。可以让我们用类写View。这样做的优点主要下面两种:

  1. 提高了代码的复用性,可以使用面向对象的技术,比如Mixin(多继承)
  2. 可以用不同的函数针对不同的HTTP方法处理,而不是通过很多if判断,提高代码可读性

平时我们写的是FBV,下面我们说一下基于类的视图

首先导入模块,才能让django找到对应的方法:

CBV模式的url写法:

运行,得到结果:

刷新,拿到表单

输入用户名,提交

应该在form表单输入:

{% csrf_token %}

再次提交得到如上结果,这就是cbv,可拓展性强,fbv写起来更简单一些,

get和post接收的参数,要进行对应.

注意:urls.py里边有name

view.py必须有name属性

FBV版的装饰器

def wrapper(func):
def inner(*args, **kwargs):
start_time = time.time()
ret = func(*args, **kwargs)
end_time = time.time()
print("used:", end_time-start_time)
return ret
return inner # FBV版添加班级
@wrapper
def add_class(request):
if request.method == "POST":
class_name = request.POST.get("class_name")
models.Classes.objects.create(name=class_name)
return redirect("/class_list/")
return render(request, "add_class.html")

装饰器表达

  装饰器的本质:一个闭包函数

  装饰器的功能:在不修改原函数及其调用方式的情况下对原函数功能进行扩展

CBV版的装饰器

from django.views import View
from django.utils.decorators import method_decorator class AddClass(View): @method_decorator(wrapper)
def get(self, request):
return render(request, "add_class.html") def post(self, request):
class_name = request.POST.get("class_name")
models.Classes.objects.create(name=class_name)
return redirect("/class_list/")

扩展:

# 使用CBV时要注意,请求过来后会先执行dispatch()这个方法,如果需要批量对具体的请求处理方法,
如get,post等做一些操作的时候,
这里我们可以手动改写dispatch方法,这个dispatch方法就和在FBV上加装饰器的效果一样。 class Login(View): def dispatch(self, request, *args, **kwargs):
print('before')
obj = super(Login,self).dispatch(request, *args, **kwargs)
print('after')
return obj def get(self,request):
return render(request,'login.html') def post(self,request):
print(request.POST.get('user'))
return HttpResponse('Login.post')

3.input标签值补充

从数据库调用各种参数,进行页面的处理,怎样通过django处理数据库

最终得到的结果是,用户输入的名字

<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta http-equiv="content-Type" charset="UTF-8">
<meta http-equiv="x-ua-compatible" content="IE=edge">
<meta name="viewport" content="width=device-width" ,initial-scale="">
<!--上边这个表示手机版的调整尺寸-->
<!--上述2个meta标签"必须"放在最前面,任何其他内容都必须跟随其后-->
<title>Title</title>
</head>
<body> <form action="/zujian/" method="post">
{% csrf_token %}
用户名: <input type="text" name="username" value="xxx">
<input type="submit">
</form>
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
</ul>
{% include 'zujian.html' %}
</body>
</html>

xiaomi

"""day53_moban URL Configuration

The `urlpatterns` list routes URLs to views. For more information please see:
https://docs.djangoproject.com/en/1.11/topics/http/urls/
Examples:
Function views
1. Add an import: from my_app import views
2. Add a URL to urlpatterns: url(r'^$', views.home, name='home')
Class-based views
1. Add an import: from other_app.views import Home
2. Add a URL to urlpatterns: url(r'^$', Home.as_view(), name='home')
Including another URLconf
1. Import the include() function: from django.conf.urls import url, include
2. Add a URL to urlpatterns: url(r'^blog/', include('blog.urls'))
"""
from django.conf.urls import url
from django.contrib import admin
from app01 import views
urlpatterns = [
# url(r'^admin/', admin.site.urls),
url(r'^index/', views.index),
url(r'^user/', views.user),
url(r'^order/', views.order),
url(r'^zujian/', views.zujian), #CBV模式的url写法
url(r'^cbv/', views.MyView.as_view(name='sss')),
]

urls.py

from django.shortcuts import render,HttpResponse
from django.views import View # Create your views here.
def index(request):
return render(request,'index.html') def user(request):
return render(request,'usercenter.html') def order(request):
return render(request,'order.html') def zujian(request):
if request.method=='POST':
uname=request.POST.get('username')
print(uname)
return HttpResponse('OK')
return render(request,'xiaomi.html') class MyView(View):
name='xxx'
def get(self,request):
return render(request,'xiaomi.html')
def post(self,request):
return HttpResponse('hello')

views.py

4.ORM创建表

ORM 对象关系映射

怎样通过数据库调用各种参数?
之前操作数据库的三种方式:pymysql,cmd,Navicat

学完orm,原生sql几乎就不写了

类对应数据库中的表,          (类====>表)

类实例化一个对象,我们就得到一条记录  (类对象===>记录)

类中的属性,对应mysql中的字段,        (类属性====>字段)

数据库的变更,只需要简单修改一些配置引擎就可以进行迁移了.

类.属性名,我们就拿到了属性对应的值.

orm就像一个引擎一样,

sqlachemy开源(功能稍弱),orm没有开源(功能更强大一些),

新创建一个项目,开始测试功能!!!
原来app中的models.py需要连接pymysql进行写语句进行测试.

磁盘是存储数据的,pymysql写完数据,存到磁盘,

orm把类对象转化成sql语句,存储到磁盘,再拿到orm上.

django不要深抠,关注实现功能就可以了,会用,用熟练就行

继承,类是创建表,属性表示字段

第一张表

from django.db import models
# Create your models here.
class Book(models.Model):
id=models.AutoField(primary_key=True)
#主键自增字段
title=models.CharField(max_length=32)
#书名,字符串,后边必须写长度
price=models.DecimalField(max_digits=16,decimal_places=2)
#mysql中有float,double,decimal(单双精度,精准)
#float(12,6) ,总长度是12,其中6位是小数长度
#面试会用到mysql,还是需要复习的!!!!!
pub_time=models.DateField()
#出版日期
publish=models.CharField(max_length=20)
#出版社
# id=models.PrimaryFied()
#主键字段,但是没有自增,现在去掉了

在下面的,输入命令,(python manage.py makemigrations)

结果:

项目中多了红框中的内容.

这就是一个记录,记录了修改了什么!!!

执行命令:(python manage.py migrate)

db.sqlite3,是嵌套在django里边的数据库,操作简单,默认是这个,

观察pycharm右侧是否有下图:

,如果没有,我们点击View里边的Tool Buttons按钮,就可以显示了.

右侧的Database,,出现下图

将左侧框里边的  db.sqlite3,左键拉到上图的框中,得到如下图

这是因为第一次,需要下载,其他的数据库也是一样

先点击下载,(下载的位置变成下图的样子)

然后apply(应用),最后选择OK

下边里面是django自带的内容

输入完两条指令,python会在settings.py里边,找到下图:installed_apps里边的东西

上图里边的最后一条,注册了app01,因为添加了app01

执行两条指令的时候,python会扫描这些被安装的应用,上边几个都是自带的应用,而最后一个是自己安装的应用,每个自己安装的应用,都需要自己进行配置一下.这是自己创建了,通过扫描app01里边的models.py

其实在apps.py里边就有这个配置

也可以写成下面这种,也就是说,写上下两种都可以

需求:现在我们再创建一个app,进行相关的操作练习一下.

创建app的命令是=>(django-admin startapp app02)

写下面的程序,现在数据库已经发生了更改.

无论在数据库中的那张表中数据库做了修改,都需要重新执行这两条指令:

python manage.py makemigrations

python manage.py migrate

记住这样就可以了

我们看到了,这个结果没有发生变化.

这时候,我们进行下面的操作:(将app02放在下面的settings.py文件里边)

这时候,我们再执行刚才的两条命令

在app02下多了migrations文件,也就是执行的记录

点击刷新前:

点击刷新后:(多了一张食物表)

双击表,我们可以看到对应的结构:

注意,这是pycharm帮助提供的,不是django帮助提供的东西

每张表,必须有一个自增字段,也就是如上图显示的一样,如果我们创建的时候不写,内部会给我们提供一个

注意,通过类创建表,类名和数据库生成的表名的区别

Book类名对应app01_book表名

Food类名对应app02_food表名

以上全是sqllite3里边的一些配置和操作.

下面我们进行mysql的一些操作.

在settings.py里边默认写的是sqlite3:

现在不用了,先断开,点击红色按钮,再移除这个db数据库即可

这时候,数据的记录是不需要了,删除就可以了,留着可能会有一些其他的问题,将红框内的删除.

配置mysql文件

首先,修改配置文件settings.py的配置

创建orm1的库.

我们发现多了一个库

这时候,我们再修改配置文件

将刚刚创建好的orm1配置上.

这时候,我们发现没有,mysqldb模块

5.pycharm连接mysql

默认用的是mysqldb这个模块,进行了连接的,用到这个地方,安装也没有用,这个模块只支持到python3.4,我们该如何处理?

我们通过pymysql连接数据库即可,也是这样操作的,如何配置呢?

在项目文件中找到__init__py.

,这时候,再运行,那两条命令.

第一条命令表示创建记录,第二条命令表示创建表

运行完成也就,创建成功了.

这时候,我们再在CMD窗口里边,展示所有的表.如上图,可以看到已经创建成功了.

这时候查表,我们可以看到查出的结果是空的,注意这里的表名是app01_book

这是django做的优化机制.并且全部是小写,必须记住这些东西.

只要一加载这个项目,就会执行这个文件.,所以放到了这个项目的__init__.py的文件下.

此时,我们也就将表创建成功了.

这时候,我们可以用pycharm给我们提供的Navicat功能界面,操作和连接sqlite3数据库一样

依次找到,这些步骤操作.,点击进入,看下有没有下载,没有下载下来,要先下载下来.

ok之后,弹出下图:

右侧,得到结果.

注意,这时候,是两个客户端,一个是django提供的,一个是pycharm提供的.

6.图书管理系统增加和查询

(1)更多字段和参数

  每个字段有一些特有的参数,例如,CharField需要max_length参数来指定VARCHAR数据库字段的大小。还有一些适用于所有字段的通用参数。 这些参数在文档中有详细定义,这里我们只简单介绍一些最常用的:

更多字段:

<1> CharField
字符串字段, 用于较短的字符串.
CharField 要求必须有一个参数 maxlength, 用于从数据库层和Django校验层限制该字段所允许的最大字符数. <2> IntegerField
#用于保存一个整数. <3> FloatField
一个浮点数. 必须 提供两个参数: 参数 描述
max_digits 总位数(不包括小数点和符号)
decimal_places 小数位数
举例来说, 要保存最大值为 999 (小数点后保存2位),你要这样定义字段: models.FloatField(..., max_digits=5, decimal_places=2)
要保存最大值一百万(小数点后保存10位)的话,你要这样定义: models.FloatField(..., max_digits=17, decimal_places=10) #max_digits大于等于17就能存储百万以上的数了
admin 用一个文本框(<input type="text">)表示该字段保存的数据. <4> AutoField
一个 IntegerField, 添加记录时它会自动增长. 你通常不需要直接使用这个字段;
自定义一个主键:my_id=models.AutoField(primary_key=True)
如果你不指定主键的话,系统会自动添加一个主键字段到你的 model. <5> BooleanField
A true/false field. admin 用 checkbox 来表示此类字段. <6> TextField
一个容量很大的文本字段.
admin 用一个 <textarea> (文本区域)表示该字段数据.(一个多行编辑框). <7> EmailField
一个带有检查Email合法性的 CharField,不接受 maxlength 参数. <8> DateField
一个日期字段. 共有下列额外的可选参数:
Argument 描述
auto_now 当对象被保存时,自动将该字段的值设置为当前时间.通常用于表示 "last-modified" 时间戳.
auto_now_add 当对象首次被创建时,自动将该字段的值设置为当前时间.通常用于表示对象创建时间.
(仅仅在admin中有意义...) <9> DateTimeField
一个日期时间字段. 类似 DateField 支持同样的附加选项. <10> ImageField
类似 FileField, 不过要校验上传对象是否是一个合法图片.#它有两个可选参数:height_field和width_field,
如果提供这两个参数,则图片将按提供的高度和宽度规格保存.
<11> FileField
一个文件上传字段.
要求一个必须有的参数: upload_to, 一个用于保存上载文件的本地文件系统路径. 这个路径必须包含 strftime #formatting,
该格式将被上载文件的 date/time
替换(so that uploaded files don't fill up the given directory).
admin 用一个<input type="file">部件表示该字段保存的数据(一个文件上传部件) . 注意:在一个 model 中使用 FileField 或 ImageField 需要以下步骤:
(1)在你的 settings 文件中, 定义一个完整路径给 MEDIA_ROOT 以便让 Django在此处保存上传文件.
(出于性能考虑,这些文件并不保存到数据库.) 定义MEDIA_URL 作为该目录的公共 URL. 要确保该目录对
WEB服务器用户帐号是可写的.
(2) 在你的 model 中添加 FileField 或 ImageField, 并确保定义了 upload_to 选项,以告诉 Django
使用 MEDIA_ROOT 的哪个子目录保存上传文件.你的数据库中要保存的只是文件的路径(相对于 MEDIA_ROOT).
出于习惯你一定很想使用 Django 提供的 get_<#fieldname>_url 函数.举例来说,如果你的 ImageField
叫作 mug_shot, 你就可以在模板中以 {{ object.#get_mug_shot_url }} 这样的方式得到图像的绝对路径. <12> URLField
用于保存 URL. 若 verify_exists 参数为 True (默认), 给定的 URL 会预先检查是否存在( 即URL是否被有效装入且
没有返回404响应).
admin 用一个 <input type="text"> 文本框表示该字段保存的数据(一个单行编辑框) <13> NullBooleanField
类似 BooleanField, 不过允许 NULL 作为其中一个选项. 推荐使用这个字段而不要用 BooleanField 加 null=True 选项
admin 用一个选择框 <select> (三个可选择的值: "Unknown", "Yes" 和 "No" ) 来表示这种字段数据. <14> SlugField
"Slug" 是一个报纸术语. slug 是某个东西的小小标记(短签), 只包含字母,数字,下划线和连字符.#它们通常用于URLs
若你使用 Django 开发版本,你可以指定 maxlength. 若 maxlength 未指定, Django 会使用默认长度: 50. #在
以前的 Django 版本,没有任何办法改变50 这个长度.
这暗示了 db_index=True.
它接受一个额外的参数: prepopulate_from, which is a list of fields from which to auto-#populate
the slug, via JavaScript,in the object's admin form: models.SlugField
(prepopulate_from=("pre_name", "name"))prepopulate_from 不接受 DateTimeFields. <13> XMLField
一个校验值是否为合法XML的 TextField,必须提供参数: schema_path, 它是一个用来校验文本的 RelaxNG schema #的文件系统路径. <14> FilePathField
可选项目为某个特定目录下的文件名. 支持三个特殊的参数, 其中第一个是必须提供的.
参数 描述
path 必需参数. 一个目录的绝对文件系统路径. FilePathField 据此得到可选项目.
Example: "/home/images".
match 可选参数. 一个正则表达式, 作为一个字符串, FilePathField 将使用它过滤文件名.
注意这个正则表达式只会应用到 base filename 而不是
路径全名. Example: "foo.*\.txt^", 将匹配文件 foo23.txt 却不匹配 bar.txt 或 foo23.gif.
recursive可选参数.要么 True 要么 False. 默认值是 False. 是否包括 path 下面的全部子目录.
这三个参数可以同时使用.
match 仅应用于 base filename, 而不是路径全名. 那么,这个例子:
FilePathField(path="/home/images", match="foo.*", recursive=True)
...会匹配 /home/images/foo.gif 而不匹配 /home/images/foo/bar.gif <15> IPAddressField
一个字符串形式的 IP 地址, (i.e. "24.124.1.30").
<16> CommaSeparatedIntegerField
用于存放逗号分隔的整数值. 类似 CharField, 必须要有maxlength参数.

具体用到再细说,

更多参数:

(1)null

如果为True,Django 将用NULL 来在数据库中存储空值。 默认值是 False.

(1)blank

如果为True,该字段允许不填。默认为False。
要注意,这与 null 不同。null纯粹是数据库范畴的,而 blank 是数据验证范畴的。
如果一个字段的blank=True,表单的验证将允许该字段是空值。如果字段的blank=False,该字段就是必填的。 (2)default 字段的默认值。可以是一个值或者可调用对象。如果可调用 ,每有新对象被创建它都会被调用,如果你的字段没有设置可以为空,那么将来如果我们后添加一个字段,这个字段就要给一个default值 (3)primary_key 如果为True,那么这个字段就是模型的主键。如果你没有指定任何一个字段的primary_key=True,
Django 就会自动添加一个IntegerField字段做为主键,所以除非你想覆盖默认的主键行为,
否则没必要设置任何一个字段的primary_key=True。 (4)unique 如果该值设置为 True, 这个数据字段的值在整张表中必须是唯一的 (5)choices
由二元组组成的一个可迭代对象(例如,列表或元组),用来给字段提供选择项。 如果设置了choices ,默认的表单将是一个选择框而不是标准的文本框,<br>而且这个选择框的选项就是choices 中的选项。
(6)db_index
  如果db_index=True 则代表着为此字段设置数据库索引。 DatetimeField、DateField、TimeField这个三个时间字段,都可以设置如下属性。 (7)auto_now_add
配置auto_now_add=True,创建数据记录的时候会把当前时间添加到数据库。 (8)auto_now
配置上auto_now=True,每次更新数据记录的时候会更新该字段,标识这条记录最后一次的修改时间。

怎样添加记录?
写一个页面,写一个函数,将后端mysql数据库所有数据读取出来,放到前端页面展示

写一条数据到app01_book表中

注意,左边这个才是保存按钮.

首先是查:

urls.py写法

先写一个展示数据的页面,book_list.html,目前什么都没有写

运行,我们看一下all_books打印的是什么!!!

all_books=models.Book.objects.all()    #拿到所有对象

QuerySet类型是一种新的数据类型,ORM提供的一种新的数据类型.里边放的是一个个类的对象,每个对象对应一条记录

QuerySet类型操作和列表的操作是一样的,

all_books=models.Book.objects.all()[0]  #拿到第一个对象
all_books=models.Book.objects.all()[0].title  #拿到第一个对象的名字

修改如上如,我们在运行,查看

在浏览器中输入(http://127.0.0.1:8000/book_list/)

服务端可以得到结果如下:

修改成第二条记录:

运行:

浏览器中输入地址(http://127.0.0.1:8000/book_list/)

服务端得到如下

修改:

这时候,我们再写,book_list是怎样展示的,也就是写book_list.html文件

<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta http-equiv="content-Type" charset="UTF-8">
<meta http-equiv="x-ua-compatible" content="IE=edge">
<meta name="viewport" content="width=device-width" ,initial-scale="1">
<!--上边这个表示手机版的调整尺寸-->
<!--上述2个meta标签"必须"放在最前面,任何其他内容都必须跟随其后-->
<title>Title</title>
</head>
<body>
<table>
<thead>
<tr>
<th>id</th>
<th>书名</th>
<th>价钱</th>
<th>出版时间</th>
<th>出版社</th>
</tr>
</thead>
<tbody>
{% for one_book in all_books %}
<tr>
<td>{{ one_book.id }}</td>
<td>{{ one_book.title }}</td>
<td>{{ one_book.price }}</td>
<td>{{ one_book.pub_time }}</td>
<td>{{ one_book.publish }}</td>
</tr>
{% endfor %}
</tbody>
</table>
</body>
</html>

运行,输入地址,我们拿到如下界面

为了让界面好看一些,我们配置动态文件,cdn,也就是网络版的bootstrap,如下图内,红框内的地址.

添加的cdn文件

运行:

我们再在table里边添加属性:class="table"

运行:得到如下结果:

运用栅格系统,居中,自己占6份,移动3份

具体代码:

<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta http-equiv="content-Type" charset="UTF-8">
<meta http-equiv="x-ua-compatible" content="IE=edge">
<meta name="viewport" content="width=device-width" ,initial-scale="1">
<!--上边这个表示手机版的调整尺寸-->
<!--上述2个meta标签"必须"放在最前面,任何其他内容都必须跟随其后-->
<title>Title</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
</head>
<body> <div class="container">
<div class="row">
<div class="col-md-6 col-md-offset-3">
{#表开始#}
<table class="table">
<thead>
<tr>
<th>id</th>
<th>书名</th>
<th>价钱</th>
<th>出版时间</th>
<th>出版社</th>
</tr>
</thead>
<tbody>
{% for one_book in all_books %}
<tr>
<td>{{ one_book.id }}</td>
<td>{{ one_book.title }}</td>
<td>{{ one_book.price }}</td>
<td>{{ one_book.pub_time }}</td>
<td>{{ one_book.publish }}</td>
</tr>
{% endfor %}
</tbody>
</table>
{#表结束#}
</div>
</div>
</div> </body>
</html>

运行:结果

向下移动100px

加上外边框:

得到结果:

再写一个添加书的功能

运行,输入地址,提交

双击右边的书籍表,得到这样的图表,有时候需要刷新一下

运行:

反应慢,需要刷新一下.

添加完成之后,应该做什么?应该显示添加之后的结果

这样写,就将路径写死了,

应该先起好别名

通过别名进行反向解析,

其实不用 reverse也是可以的,

在views.py导入模块

from django.urls import reverse

访问地址:得到结果如下.

如何通过按钮实现"添加",删除功能?还有,上边显示的出版日期不认识,怎么办?

通过过滤器实现:(在book_list.html中修改)

得到如下结果:

"点击"添加数据,我们可以跳转到新的页面进行添加操作?
新建一个"add_book.html"页面.

在通过解析,将点击之后,地址反向到"添加书籍"上

运行,点击添加书籍

跳转到,

<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta http-equiv="content-Type" charset="UTF-8">
<meta http-equiv="x-ua-compatible" content="IE=edge">
<meta name="viewport" content="width=device-width" ,initial-scale="1">
<!--上边这个表示手机版的调整尺寸-->
<!--上述2个meta标签"必须"放在最前面,任何其他内容都必须跟随其后-->
<title>Title</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap.min.css"
integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
</head>
<body> <div class="container">
<div class="row">
<div class="col-md-6 col-md-offset-3"> {#表单开始#}
<form class="form-horizontal" action="{% url 'add_book' %}" method="post">
{#action 属性规定当提交表单时,向何处发送表单数据。#}
{% csrf_token %}
{#安全认证#}
<div class="form-group">
<label for="book_name" class="col-sm-2 control-label">书名</label>
<div class="col-sm-10">
<input type="text" class="form-control" id="book_name" placeholder="书名" name="book_name">
</div>
</div> <div class="form-group">
<label for="book_price" class="col-sm-2 control-label">价格</label>
<div class="col-sm-10">
<input type="text" class="form-control" id="book_price" placeholder="价格" name="book_price">
</div>
</div> <div class="form-group">
<label for="book_time" class="col-sm-2 control-label">出版时间</label>
<div class="col-sm-10">
<input type="text" class="form-control" id="book_time" placeholder="出版时间" name="book_time">
</div>
</div> <div class="form-group">
<label for="book_publish" class="col-sm-2 control-label">出版社</label>
<div class="col-sm-10">
<input type="text" class="form-control" id="book_publish" placeholder="出版社" name="book_publish">
</div>
</div> <div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<input type="submit" value="保存" class="btn btn-default">
</div>
</div>
</form>
{#表单结束#}
</div>
</div>
</div> </body>
</html>

修改之后的add_book.html

刷新页面:

添加下面的代码:(向下移动了100px)

将保存放在右侧,颜色改成绿色

出版时间,里边的input标签的type属性改成从text改成date

现在的需求是,点击'保存',将数据发送到book_list.html页面和数据库中.

点击"保存"之后,返回页面

结果:成功添加进去了.

服务端得到的结果:

另一种创建方式,得到另一条记录

浏览器得到的结果:

保存

服务端得到的结果:

记录返回的结果应该是,添加完成之后的列表,所以,我们需要进行,修改返回返回的页面

展示页面:

点击保存:

重点::添加数据的语句,查找数据的语句

还有删改

刷新页面:

两个button中间加个空格

设置垂直居中,

实现了居中的效果:

  !important 的使用。

  !important:设置权重为无限大 
  !important 不影响继承来的权重,只影响选中的元素。不要随便使用!important,因为使用它会影响页面的布局

7.图书管理系统删除和更改操作的ORM演示

打印日志的配置文件,在settings里边放进去:

LOGGING = {
'version': 1,
'disable_existing_loggers': False,
'handlers': {
'console':{
'level':'DEBUG',
'class':'logging.StreamHandler',
},
},
'loggers': {
'django.db.backends': {
'handlers': ['console'],
'propagate': True,
'level':'DEBUG',
},
}
}  

重启项目,就可以看到一些语句了

运行:

服务端什么结果都没有.

修改

运行:

这个服务器端应该显示一条记录,但是结果是空的.

运行:

显示出4条结果

思考如何让上边类的对象显示出来?

获得对象的地址

如何显示字符串的内容?

在models里自定义一个str,不需要重启数据库,只需要重新运行项目即可

再运行项目,得到结果

filter里边的条件暂且用不了or

全部删除,出版社是"18期出版社"的,数据,展示的应该是空

运行,

展示的是4本,这样的书,

书籍列表里边也没有书了,也就是没有"18期出版社"的书籍了

运行:

点击'刷新',得到下面的结果:

再看book_list,多了下面的数据.

今日内容
.模板渲染中的组件:{% include ‘xx.html’ %}
.CBV通过类的方式来写视图
from django.views import View
class My(View):
def get(self,request): #获取get请求的
self.xxx()
pass
def post():
pass
def xxx():
pass #其他请求方法
#如何找到这个类?
Url(r‘^index/’,views.My.as_view()) FBV这是通过函数的形式来写视图 函数装饰器:
def wrapper(fn):
def inner(*args,**kwargs):
print(‘Before’)
ret=fn(*args,**kwargs)
print(‘after’)
return ret
return inner Cbv装饰器
from django.views import View
from django.utils.decorators import method_decorator
@method_decorator(wrapper,name=’get’)
class My(View):
@method_decorator(wrapper)
def get(self,request):
self.xxx()
pass
def post()
pass
def xxx()
pass
url(r‘^index/’,views.My.as_view()) ORM 对象关系映射
类 ----- 表
类对象--- 记录
类属性--- 字段 应用里面的models文件里面写类 class Book(models.Model): id = models.AutoField(primary_key=True)
title = models.CharField(max_length=,unique=True)
price = models.DecimalField(max_digits=,decimal_places=)
pub_time = models.DateField()
publish = models.CharField(max_length=) def __str__(self):
return self.title 连接mysql
mysql里面创建一个库
配置mysql的链接(引擎)
Settings :database
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME':'bms',      # 要连接的数据库,连接前需要创建好
'USER':'root',       # 连接数据库的用户名
'PASSWORD':'',       # 连接数据库的密码
'HOST':'127.0.0.1', # 连接主机,默认本级
'PORT':     # 端口 默认3306
}
} 项目那个包里面的init文件里面写上:
import pymysql
pymysql.install_as_MySQLdb() 如果先添加了app应用的话,别忘了在settings配置文件里面的installapp那个列表里面注册上你的app
引入app
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'app01.apps.App01Config', 方式1
'app02', 方式2 ] 生成到MySQL数据库里面
Python manage.py makemigrations
Python manage.py migrate 增:
方式1 :book_obj = models.Book(title=’xx’,pub=’xx’)
book_obj.save()
方式2:models.Book.objects.create(title=’xx’,pub=’xx’)
删:
models.Book.objects.filter(title=’冬瓜’,id=).delete()
改:
models.Book.objects.filter(title=’冬瓜’,id=).update(title=’冬瓜’) 查:
查询所有的:models.Book.objects.all()
查询筛选的:models.Book.objects.filter(title=’冬瓜’,id=) and多添加查询
上边两个都是querset类型

今日内容总结

对上边的问题,进一步调试:

最终得到结果:

对上边出错的原因可能是,没有刷新数据库等原因吧

巨蟒python全栈开发django5:组件&&CBV&FBV&&装饰器&&ORM增删改查的更多相关文章

  1. day054 组件 CBV FBV 装饰器 ORM增删改查

    组件: ​ 把一小段HTML 放在一个HTML中 nav.html ​ 使用: ​ {% include ‘nav.html ’ %} 一. FBV 和CBV 1.FBV(function base ...

  2. 巨蟒python全栈开发django6: FBV&CBV&&单表查询的其他方法

    练习CBV用法 截图中的action="/cbv/",应该是这样 上边红图,说明mysql有问题,需要重启一下 返回,输入的内容 @wrapper==>cbv=wrapper ...

  3. 巨蟒python全栈开发linux之centos1

    1.linux服务器介绍 2.linux介绍 3.linux命令学习 linux默认有一个超级用户root,就是linux的皇帝 注意:我的用户名是s18,密码是centos 我们输入密码,点击解锁( ...

  4. 巨蟒python全栈开发-第11阶段 ansible_project2

    一个NB的网站: https://www.toolfk.com/ CDN:将用户的需求送到最近的节点:内容分发网络 有些是专门做CDN的工具 常用的markdown是需要知道的,短信有字数限制. we ...

  5. 巨蟒python全栈开发-第4天 列表&元组&range

    今日内容大纲 1. 什么是列表 定义: 能装对象的对象 在python中使用[]来描述列表, 内部元素用逗号隔开. 对数据类型没有要求 列表存在索引和切片. 和字符串是一样的. 2. 相关的增删改查操 ...

  6. 巨蟒python全栈开发flask8 MongoDB回顾 前后端分离之H5&pycharm&夜神

    1.MongoDB回顾 .启动 mongod - 改变data/db位置: --dbpath D:\data\db mongod --install 安装windows系统服务 mongod --re ...

  7. 巨蟒python全栈开发flask7 语音识别升级版&&mongoDB

    1.web简陋版玩具 首先,复制上一节课的内容,将其中的语音文件删除掉, 放入三个文件,然后,我们需要在app写入下面的内容 下图是需要修改的地方: Recorder_ok.js是一个web录音的工具 ...

  8. 巨蟒python全栈开发flask2

    内容回顾: 上节回顾: Flask .response 三剑客: render_template 模板 redirect 重定向 - URL地址 "" 字符串 HTTPRespon ...

  9. 巨蟒python全栈开发-第5天 字典&集合

    今日大纲: 1.什么是字典 字典是以key:value的形式来保存数据,用{}表示. 存储的是key:value 2.字典的增删改查(重点) (1) 添加 dic[新key] = 值 setdefau ...

随机推荐

  1. 火车票订票API 用PHP完成火车票订票流程

    本教程用来演示聚合数据-火车票订票接口的使用流程. 配置好PHP环境,PHP版本最好大于5.5 去聚合数据-火车票订票接口申请key:http://www.juhe.cn/docs/api/id/17 ...

  2. 百度MUX:APP动效之美需内外兼修

    移动互联网时代已经到来.APP已如天空的繁星.数也数不清.随着手机硬件的不断升级,实现炫酷且流畅的动效不再是遥远的梦想.假设你是APP达人,喜欢试用各种APP,你肯定会发现越来越多的APP開始动效化. ...

  3. Tomcat中work目录的作用

    今天在修改了某个jsp后发现:tomcat容器启动后,访问该jsp返回的结果依然是修改之前的内容,略感不解,于是乎研究了一下Tomcat中work目录的作用. Tomcat中work目录的作用: js ...

  4. C# 播放H264裸码流

    要播放H264裸码流,可以分拆为以下三个工作: 1.解码H264裸码流获取YUV数据 2.将YUV数据转换为RGB数据填充图片 3.将获取的图片进行显示 要完成工作1,我们可以直接使用海思的解码库,由 ...

  5. 锁定窗口,禁止更新的win32函数

    [DllImport("user32.dll", EntryPoint = "LockWindowUpdate", SetLastError = true, E ...

  6. 打开eclipse中文件所在文件夹

    在myeclipse中选中文件后能够打开文件所在文件夹,可是eclipse中没有直接打开文件路径的功能.须要我们自己加入. 选择:Run -> External Tools -> Exte ...

  7. Atitit.wrmi web rmi框架新特性

    Atitit.wrmi web rmi框架新特性 1. V1d  新特性1 1.1. 增加了精确参数1 1.2. 增加了req参数,命名参数模式..1 1.3. 增加了globale  传递隐含参数r ...

  8. Android 第三方应用广告拦截实现

    前段时间,公司制造的机器里应用装有不良广告,严重影响了儿童客户使用者的思想健康.导致被人投诉. 于是乎.就有了想研发一款相似于360广告屏蔽的应用的念头.嗯.事情就是这样.如今切入主题. 眼下市场上有 ...

  9. python 第三方库下载地址

    http://www.lfd.uci.edu/~gohlke/pythonlibs/#lxml

  10. 使用pycharm手动搭建python语言django开发环境(五) 使用日志模块打日志

    1.在项目的settings.py中增加日志相关声明 #增加日志设置 LOGGING = { 'version': 1, 'disable_existing_loggers': False, 'fil ...