0.本周知识点预览
- django 基础
1.django 基础
1.路由系统
1.初始环境
需要安装django,创建project、app,启动django
相关命令如下:
django-admin startproject day18(项目名)
cd day18
python3 manage.py startapp day18_app(app名)
路由系统主要配置文件:urls.py !!!
2.路由关系
1.普通关系
在urls.py中的配置如下:
url(r'^test1/',views.test1),
当配置好urls.py路由文件后,这个配置分为两部分:
r'^test1/' : 代表django启动之后IP/域名后的url,这是最简单的url例子:127.0.0.1:8000/test1/
==> 寻找views.test1
def test1(request): return HttpResponse("test1 ok")
==> views.py 中的test1方法,根据返回或者渲染到页面。
2.动态关系
1.不分组
在urls.py中的配置如下:
url(r'^test2/\d+/\d+',views.test2),
当urls.py中配置好之后,会找到views.py中test2的函数
def test2(request): return HttpResponse("test2 ok")
不过在浏览器中输入地址时,需要输入http://127.0.0.1:8000/test2/23123/123123 数字就成。
2.分组
在urls.py的配置如下:
url(r'^test3/(\d+)/(\d+)',views.test3),
当urls.py中配置好之后,会找到views.py中test3的函数
def test3(request, num1 , num2): ret = int(num1) + int(num2) return HttpResponse("test3 result: %d" % ret)
不过在浏览器中输入地址,需要输入http://127.0.0.1:8000/test3/123/123 数字就成,而且!在python函数中,需要传入分组的函数,urls.py中加括号就需要在函数中传入!
3.命名分组
在urls.py中配置如下:
url(r'^test4/(?P<p1>\d+)/(?P<p2>\d+)',views.test4),
?P<分组名>
当urls.py中配置好之后,会找到views.py中test4的函数
def test4(request, p1 , p2): ret = int(p1) + int(p2) return HttpResponse("test3 result: %d" % ret)
这次传入的参数,必须是定义的分组名,p1,p2。
3.路由分发(include)
当一个项目中APP过多时,路由文件就最好在每个APP中定义,语法如下:
在主urls.py配置文件中配置:
url(r'^include/',include("day18_app.urls")),
day18_app 是APP名字,urls是其目录下的urls.py配置文件,在该文件中需配置:
from django.conf.urls import urlfrom day18_app import views urlpatterns = [ url(r'^include/', views.includetest), ]
在子urls.py中配置时,因为主配置文件已经定义路由规则是include开头,所以在子配置文件配置后,默认前边都要有include,所以该配置就是当浏览器访问url以include/include/开头时,需要访问views.includetest函数。
2.模板
1.普通变量
django代码:
def test5(request): content = "fuck" return render(request, "test5.html", {"cont":content})
解析:render方法,返回html文件,第一个参数是request,第二个参数是返回的文件,第三个参数则是模板所需参数(字典形式),把字符串传入给key:cont
这个cont会在html中用到
test5.html代码:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <h1>{{ cont }}</h1> </body> </html>
变量的调用在html文件中要用{{ 变量名 }}
2.条件语句、循环语句
在上述例子中,content = "fuck",如若改成content = [1,2,3]
则return render(request, "test5.html", {"cont":content})这个都一样
不过在html中则不一样
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> {% for i in cont %} {% if i > 2 %} <h1> {{ i }}</h1> {% endif %} {% endfor %} </body> </html>
可见在选择语句和循环语句中,都是要用{% %}来写语句,并且每个关键字都有对应的end + 关键字。
3.内置方法和自定义方法
内置方法:
同样是一样的例子,content = [a,b,c], 同样return render(request, "test5.html",)
html中的写法:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> {% for i in cont %} <h1>{{ i|upper }}</h1> {% endfor %} </body> </html>
自定义方法:
- 在settings.py中注册APP
- 必须在APP下创建一个名叫templatetags的目录,名字不能变
- 在该目录下创建python文件,如xx.py
- 该py文件需要导入模块:
from django import template from django.utils.safestring import mark_safe from django.template.base import resolve_variable, Node, TemplateSyntaxError # register必须不变 register = template.Library()
- 创建函数(函数分为filter、simple_tag两种,分别用装饰器:@register.filter或者@register.simple_tag):
- 两种函数的区别:filter类函数可以返回作为if判断,不过参数只可以传1个,要想多传,只能传输特定分隔符的字符串在后端分隔("aa_cc_aaa"),simple_tag可以传多个参数,但是只能当函数,不能作为html中的if判断。
@register.filter def f1(value): return value + "666"
- 在html模板的头部写入:{% load xx %}
- 还用上述例子,content = "123",传入html文件
- html文件写法:
{% load xx %} <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <h1>{{ cont|f1 }}</h1> </body> </html>
4.模板的继承
模板继承主要用在,整个页面只需要刷新其中一块,这时,只需要修改其中一段html就可以,其他样式不变。
还是用上述的例子,content = [1,2,3],其余python代码不变(render返回的是子版html),模板继承主要用到html
母版:
{% load xx %} <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <h1>{{ cont|f1 }}</h1> {% block haha %} <h1>123</h1> {% endblock %} </body> </html>
重点是block endblock 这里边的可以被子版替换,haha是block 名字
子版:
{% extends "test5.html" %} <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> {% block haha %} <h1>我是子版</h1> {% endblock %} </body> </html>
子版需要继承母版,extends 加母版名字
block 定义haha这个名字,可以替换母版的样式,且子版中只有在block 和 endblock中生效
5.include html
有些时候会出现一些小块的html问加你被频繁用到,这时候可以利用include来实现小html的加载,就像python的函数
写法:
{% load xx %} <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <h1>{{ cont|f1 }}</h1> {% block haha %} <h1>123</h1> {% endblock %} {% include 'test5_sunsun.html' %} ###加上这一句 </body> </html>
在test5_sunsun.html文件中只要写上标签就可以,无需写入其他标签
test5_sunsun.html:
<h1>include html</h1>
3.Ajax
1.Ajax基础案例
利用AJAX可以做:
1、注册时,输入用户名自动检测用户是否已经存在。
2、登陆时,提示用户名密码错误
3、删除数据行时,将行ID发送到后台,后台在数据库中删除,数据库删除成功后,在页面DOM中将数据行也删除。(博客园)
就是可以实现,提交部分数据,页面不刷新也能得到结果。
urls.py配置:
url(r'^ajax_demo/',views.ajax_demo),
views.py:
def ajax_demo(request): if request.method == 'POST': ret = {"status":False, "message": ""} user = request.POST.get('user', None) pwd = request.POST.get('pwd', None) if user == "111" and pwd == "222": ret["status"] = True return HttpResponse(json.dumps(ret)) else: ret["message"] = "用户名或密码错误" return HttpResponse(json.dumps(ret)) return render(request, "ajax_demo.html")
ajax_demo.html:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <div><p>用户名:<input type="text" id="username"/></p></div> <div><p>密码:<input type="password" id="pwd"/></p></div> <input type="button" value="提交" onclick="Submit();"/> {# Ajax 依赖jQuery#} <script src="/static/jquery-1.12.4.js"></script> <script> function Submit(){ $.ajax({ {# 页面跳转的url#} url : '/ajax_demo/', type:'POST', {# data是向后台发的数据#} data: {'user': $('#username').val(),'pwd':$('#pwd').val()}, {# dataType: "json",#} success: function (data){ var data_list = JSON.parse(data); if (data_list.status){ {# 如若成功,跳转到百度#} location.href = "https://www.baidu.com"; }else { alert(data_list.message); } } }) } </script> </body> </html>
页面上:输入错误用户名密码会直接js弹窗,输入正确则跳转到百度
2.Ajax详细教程
链接:http://www.cnblogs.com/wupeiqi/articles/5703697.html
链接:http://www.w3school.com.cn/ajax/index.asp
4.数据库ORM
1.创建Model,之后可以根据Model来创建数据库表
from django.db import models class userinfo(models.Model): name = models.CharField(max_length=30) email = models.EmailField() memo = models.TextField()
1、models.AutoField 自增列 = int(11) 如果没有的话,默认会生成一个名称为 id 的列,如果要显示的自定义一个自增列,必须将给列设置为主键 primary_key=True。 2、models.CharField 字符串字段 必须 max_length 参数 3、models.BooleanField 布尔类型=tinyint(1) 不能为空,Blank=True 4、models.ComaSeparatedIntegerField 用逗号分割的数字=varchar 继承CharField,所以必须 max_lenght 参数 5、models.DateField 日期类型 date 对于参数,auto_now = True 则每次更新都会更新这个时间;auto_now_add 则只是第一次创建添加,之后的更新不再改变。 6、models.DateTimeField 日期类型 datetime 同DateField的参数 7、models.Decimal 十进制小数类型 = decimal 必须指定整数位max_digits和小数位decimal_places 8、models.EmailField 字符串类型(正则表达式邮箱) =varchar 对字符串进行正则表达式 9、models.FloatField 浮点类型 = double 10、models.IntegerField 整形 11、models.BigIntegerField 长整形 integer_field_ranges = { 'SmallIntegerField': (-32768, 32767), 'IntegerField': (-2147483648, 2147483647), 'BigIntegerField': (-9223372036854775808, 9223372036854775807), 'PositiveSmallIntegerField': (0, 32767), 'PositiveIntegerField': (0, 2147483647), } 12、models.IPAddressField 字符串类型(ip4正则表达式) 13、models.GenericIPAddressField 字符串类型(ip4和ip6是可选的) 参数protocol可以是:both、ipv4、ipv6 验证时,会根据设置报错 14、models.NullBooleanField 允许为空的布尔类型 15、models.PositiveIntegerFiel 正Integer 16、models.PositiveSmallIntegerField 正smallInteger 17、models.SlugField 减号、下划线、字母、数字 18、models.SmallIntegerField 数字 数据库中的字段有:tinyint、smallint、int、bigint 19、models.TextField 字符串=longtext 20、models.TimeField 时间 HH:MM[:ss[.uuuuuu]] 21、models.URLField 字符串,地址正则表达式 22、models.BinaryField 二进制 23、models.ImageField 图片 24、models.FilePathField 文件
null=True 数据库中字段是否可以为空 2、blank=True django的 Admin 中添加数据时是否可允许空值 3、primary_key = False 主键,对AutoField设置主键后,就会代替原来的自增 id 列 4、auto_now 和 auto_now_add auto_now 自动创建---无论添加或修改,都是当前操作的时间 auto_now_add 自动创建---永远是创建时的时间 5、choices GENDER_CHOICE = ( (u'M', u'Male'), (u'F', u'Female'), ) gender = models.CharField(max_length=2,choices = GENDER_CHOICE) 6、max_length 7、default 默认值 8、verbose_name Admin中字段的显示名称 9、name|db_column 数据库中的字段名称 10、unique=True 不允许重复 11、db_index = True 数据库索引 12、editable=True 在Admin里是否可编辑 13、error_messages=None 错误提示 14、auto_created=False 自动创建 15、help_text 在Admin中提示帮助信息 16、validators=[] 17、upload-to
2、连表关系:
- 一对多,models.ForeignKey(ColorDic)
- 一对一,models.OneToOneField(OneModel)
- 多对多,authors = models.ManyToManyField(Author)
应用场景:
一对一:在某表中创建一行数据时,有一个单选的下拉框(下拉框中的内容被用过一次就消失了)。
例如:原有含10列数据的一张表保存相关信息,经过一段时间之后,10列无法满足需求,需要为原来的表再添加5列数据。
一对多:当一张表中创建一行数据时,有一个单选的下拉框(可以被重复选择)。
例如:创建用户信息时候,需要选择一个用户类型【普通用户】【金牌用户】【铂金用户】等。
多对多:在某表中创建一行数据是,有一个可以多选的下拉框。
例如:创建用户信息,需要为用户指定多个爱好。
3、数据库操作
- 增加:创建实例,并调用save
- 更新:a.获取实例,再sava;b.update(指定列)
- 删除:a. filter().delete(); b.all().delete()
- 获取:a. 单个=get(id=1) ;b. 所有 = all()
- 过滤:filter(name='xxx');filter(name__contains='');(id__in = [1,2,3]) ;
icontains(大小写无关的LIKE),startswith和endswith, 还有range(SQLBETWEEN查询)'gt', 'in', 'isnull', 'endswith', 'contains', 'lt', 'startswith', 'iendswith', 'icontains','range', 'istartswith' - 排序:order_by("name") =asc ;order_by("-name")=desc
- 返回第n-m条:第n条[0];前两条[0:2]
- 指定映射:values
- 数量:count()
- 聚合:from django.db.models import Min,Max,Sum objects.all().aggregate(Max('guest_id'))
- 原始SQL
cursor = connection.cursor() cursor.execute('''SELECT DISTINCT first_name ROM people_person WHERE last_name = %s""", ['Lennon']) row = cursor.fetchone()