前言,Django安装
pip install django # 官网安装最新版本 pip install django -i "https://pypi.doubanio.com/simple/" # 指定安装源 pip install django --upgrate # 更新Django pip uninstall django # 卸载django pip install django==1.11.7 -i http://pypi.douban.com/simple --trusted-host pypi.douban.com # 安装指定版本django
一、Django项目的url的实现
1)创建django框架,
第一步:创建 django框架 先创建文件夹,再在cmd里面输入下面内容,项目:小说 django-admin startproject url定义 第二步 文件夹内出现相应的子文件,创建app cd blog python manage.py startapp blog #创建novel应用,会出现novel文件夹,里面有很多.py文件 python3 manage.py runserver 8080 第二步:访问 http://127.0.0.1:8000/ 首页
pycharm创建Django框架非常简单,一步到位
2)自定义url网页。HttpResponse 返回前端字符串内容
from blog import views # 添加内容 urlpatterns = [ url(r'^admin/', admin.site.urls), url(r'^show_time',views.show_time) # 添加内容 ]
from django.shortcuts import render,HttpResponse # 补充的内容 # Create your views here. # 添加的函数 def show_time(req): return HttpResponse("hello")
3行内容实现了自定义网页
3)以html文件返回给服务器。render 返回 html 内容
在上面的基础上运行
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <h1>hello world</h1> </body> </html>
def show_time(req):
return render(req,'index.html') # 修改这里即可
4)返回页面时间内容。技术点:html文件的{{ t }} ===》views.show_time里面的变量t
模板变量的使用
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <h1>hello world {{ t }}</h1> </body> </html>
from django.shortcuts import render,HttpResponse import time # Create your views here. def show_time(req): t=time.ctime() return render(req, 'index.html',locals())
也可以换一种写法
HTML中 <h1>hello world {{ time }}</h1> view.py中 def show_time(req): t=time.ctime() return render(req, 'index.html',{"time":t})
4.1)模板变量的使用
第一种:直接获取到变量 <h1>hello {{ name }}</h1> 第二种:获取到列表,使用索引取值 <h1>hello {{ name.0 }}</h1> <h1>hello {{ name.1 }}</h1> 第三种:获取到字典,使用key取值 <h1>hello {{ name.name }}</h1> 第四种:获取到对象,使用对象属性取值 <h1>hello {{ name.name }}</h1>
4.2)模板过滤器
语法格式: {{obj|filter:param}}
# 1 add : 给变量加上相应的值 # # 2 addslashes : 给变量中的引号前加上斜线 # # 3 capfirst : 首字母大写 # # 4 cut : 从字符串中移除指定的字符 # # 5 date : 格式化日期字符串 # # 6 default : 如果值是False,就替换成设置的默认值,否则就是用本来的值 # # 7 default_if_none: 如果值是None,就替换成设置的默认值,否则就使用本来的值
使用示例
#value1="aBcDe" {{ value1|upper }}<br> #value2=5 {{ value2|add:3 }}<br> #value3='he llo wo r ld' {{ value3|cut:' ' }}<br> #import datetime #value4=datetime.datetime.now() {{ value4|date:'Y-m-d' }}<br> #value5=[] {{ value5|default:'空的' }}<br> #value6='<a href="#">跳转</a>' {{ value6 }} {% autoescape off %} {{ value6 }} {% endautoescape %} {{ value6|safe }}<br> {{ value6|striptags }} #value7='1234' {{ value7|filesizeformat }}<br> {{ value7|first }}<br> {{ value7|length }}<br> {{ value7|slice:":-1" }}<br> #value8='http://www.baidu.com/?a=1&b=3' {{ value8|urlencode }}<br> value9='hello I am yuan'
4.3){% if %} 模板控制语句 if 判断
{% if num >= 100 and 8 %} {% if num > 200 %} <p>num大于200</p> {% else %} <p>num大于100小于200</p> {% endif %} {% elif num < 100%} <p>num小于100</p> {% else %} <p>num等于100</p> {% endif %} {% if %} 标签接受and,or或者not来测试多个变量值或者否定一个给定的变量 {% if %} 标签不允许同一标签里同时出现and和or,否则逻辑容易产生歧义,例如下面的标签是不合法的: {% if obj1 and obj2 or obj3 %}
4.4){% for %}标签允许你按顺序遍历一个序列中的各个元素,每次循环模板系统都会渲染{% for %}和{% endfor %}之间的所有内容
<ul> {% for obj in list %} <li>{{ obj.name }}</li> {% endfor %} </ul> #在标签里添加reversed来反序循环列表: {% for obj in list reversed %} ... {% endfor %} #{% for %}标签可以嵌套: {% for country in countries %} <h1>{{ country.name }}</h1> <ul> {% for city in country.city_list %} <li>{{ city }}</li> {% endfor %} </ul> {% endfor %} #系统不支持中断循环,系统也不支持continue语句,{% for %}标签内置了一个forloop模板变量, #这个变量含有一些属性可以提供给你一些关于循环的信息 1,forloop.counter表示循环的次数,它从1开始计数,第一次循环设为1: {% for item in todo_list %} <p>{{ forloop.counter }}: {{ item }}</p> {% endfor %} 2,forloop.counter0 类似于forloop.counter,但它是从0开始计数,第一次循环设为0 3,forloop.revcounter 4,forloop.revcounter0 5,forloop.first当第一次循环时值为True,在特别情况下很有用: {% for object in objects %} {% if forloop.first %}<li class="first">{% else %}<li>{% endif %} {{ object }} </li> {% endfor %} # 富有魔力的forloop变量只能在循环中得到,当模板解析器到达{% endfor %}时forloop就消失了 # 如果你的模板context已经包含一个叫forloop的变量,Django会用{% for %}标签替代它 # Django会在for标签的块中覆盖你定义的forloop变量的值 # 在其他非循环的地方,你的forloop变量仍然可用 #{% empty %} {{li }} {% for i in li %} <li>{{ forloop.counter0 }}----{{ i }}</li> {% empty %} <li>this is empty!</li> {% endfor %} # [11, 22, 33, 44, 55] # 0----11 # 1----22 # 2----33 # 3----44 # 4----55
5)加上jquery-3.2.1.min.js 静态文件渲染
第一步:找到存放位置 在顶级目录下创建static文件夹,存放jquery-3.2.1.min.js文件 第二步:添加配置路径。settings.py STATIC_URL = '/static/' STATICFILES_DIRS=(os.path.join(BASE_DIR,"static"),) 添加位置 第三步:html加入文件 <script src="/static/jquery-3.2.1.min.js"></script> <script> $("h1").css("color","red") </script>
特别注意: <script src="/static/jquery-3.2.1.min.js"></script> 这里的static对应的是。STATIC_URL = '/static/' 这里的 STATICFILES_DIRS=(os.path.join(BASE_DIR,"static"),) 这里对应的是文件夹的static名字
6)引用jquery的推荐方法
<head> <meta charset="UTF-8"> {% load staticfiles %} # 增加的方法 <title>Title</title> </head> <body> <h1>hello world {{ time }}</h1> {#<script src="/static/jquery-3.2.1.min.js"></script>#} 原来的方法 <script src="{% static 'jquery-3.2.1.min.js' %}"></script> 推荐使用的方法
二、简单的注册页面写入
1)注册页面使用get 请求时
第一步:添加路由 urls.py里面 url(r"register",views.register) 第二步:定义视图函数 views.py里面添加函数 def register(request): print(request.GET) print(request.GET.get('user')) return render(request,'register.html') 第三步:templates里面添加 register.html 文件 写入 register.html 文件
register.html文件
<body> <h1>学生注册</h1> <hr> <form action="http://127.0.0.1:8000/register" method="get"> <p>姓名<input type="text" name="user"></p> <p>年龄<input type="text" name="age"></p> <p>爱好<input type="checkbox" name="hobby" value="1">篮球 <input type="checkbox" name="hpbby" value="2">篮球 <input type="checkbox" name="hobby" value="3">篮球 </p> <p><input type="submit">提交</p> </form> </body> </html>
都可以实现 <form action="http://127.0.0.1:8000/register/" method="post"> <form action="/register/" method="post">
2)注册页面使用 post 请求时
需要关闭settings.py里面的安全机制 'django.middleware.csrf.CsrfViewMiddleware',。否则请求会发生错误
<body> <h1>学生注册</h1> <hr> <form action="http://127.0.0.1:8000/register" method="post"> <p>姓名<input type="text" name="user"></p> <p>年龄<input type="text" name="age"></p> <p>爱好<input type="checkbox" name="hobby" value="1">篮球 <input type="checkbox" name="hpbby" value="2">篮球 <input type="checkbox" name="hobby" value="3">篮球 </p> <p><input type="submit">提交</p> </form> </body> </html>
def register(request): print(request.POST) print(request.POST.get('user')) if request.method == "POST": return HttpResponse("success!") # POST 请求之后返回的内容 return render(request,'register.html')
3)路由定义别名,实现动态的路由变化
第一步:路由定义别名 url(r"register", views.register,name="reg") 第二步:修改register.html <head> {% load staticfiles %} ........ <form action="{% url 'reg' %}" method="post">
4)url 路由分发(重点)
先在全局的urls文件中修改
from django.conf.urls import url,include # 导入include from django.contrib import admin from blog import views urlpatterns = [ url(r'^admin/', admin.site.urls), url(r'^blog/',include('blog.urls')) # 指向blog路由 ]
再在app里面添加urls文件
from django.conf.urls import url,include from django.contrib import admin from blog import views urlpatterns = [ url(r'^show_time',views.show_time), url(r"register", views.register,name="reg"), ]
访问访问效果
由 http://127.0.0.1:8000/register http://127.0.0.1:8000/show_time 变成了 http://127.0.0.1:8000/blog/register http://127.0.0.1:8000/blog/show_time
5)url路由跳转。redirect (重点)
urlpatterns = [ url(r'^show_time',views.show_time), url(r"register", views.register,name="reg"), 注册界面 url(r'login',views.login), 被跳转的登录界面 ] 第二步:定义函数 def register(request): print(request.POST) user = request.POST.get('user') if user == "yuan": return redirect("/blog/login/") # 跳转到指定的login路由 return render_to_response("register.html") def login(req): return render(req,"login.html")
6)补充内容
# return render(request,'register.html') 建议用这个 等效于 return render_to_response("register.html")
三、url的扩展,CBV模式(url==》class)
URL ---> 函数 ---> FBV
URL ---> 类 ---> CBV
1)匹配url规则模式,至上而下,匹配视图类
urlpatterns = [ url(r'^admin/',admin.site.urls), url(r'^inx$',views.inx), # 由于前面已经有inx,要匹配到inxd,一定要在后面加$ url(r'^inxd$',views.index), url(r'^cbv$',views.CBV.as_view()), # 匹配 views 里面的 class ]
2)视图类的创建
from django.views import View class CBV(View): def get(self,request): return HttpResponse('CBV.GET') def post(self,request): return HttpResponse('CBV.POST')
3)自定义视图类的创建,类的扩展
from django.views import View class CBV(View): def dispatch(self,request,*args,**kargs): result = super(CBV,self).dispatch(request,*args,**kargs) return result def get(self,request): # 根据请求头中的request method进行自动执行 # return HttpResponse('CBV.GET') return render(request,'cbv.html') def post(self,request): return HttpResponse('CBV.POST')
四、orm对models中创建表的操作
1) 选择数据库的引擎
第一种默认的数据库引擎。sqlite3
DATABASES = { 'default': { 'ENGINE': 'django.db.backends.sqlite3', 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'), } }
第二种,mysql数据库
# DATABASES = { # 'default': { # 'ENGINE': 'django.db.backends.sqlite3', # 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'), # } # } DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', 'NAME': 'books', #你的数据库名称 'USER': 'root', #你的数据库用户名 'PASSWORD': '', #你的数据库密码 'HOST': '', #你的数据库主机,留空默认为localhost 'PORT': '3306', #你的数据库端口 } }
需要替换驱动把mysqldb替换成pymysql
django默认你导入的驱动是MySQLdb,可是MySQLdb对于py3有很大问题,所以我们需要的驱动是PyMySQL
所以,我们只需要找到项目名文件下的__init__,在里面写入:
import pymysql
pymysql.install_as_MySQLdb()
2)创建表
第一步:确定配置文件加入了app INSTALLED_APPS = [ ................. 'blog' ] 第二步:在models.py中写入class 表结构 # create table book( # name varchar(20), # price float(4,2), # ) class Book(models.Model): name=models.CharField(max_length=20) price=models.FloatField() pub_date=models.DateField() 第三步:生成数据库 python manage.py makemigrations python manage.py migrate
from django.db import models # Create your models here. # create table book( # name varchar(20), # price float(4,2), # ) class Book(models.Model): name = models.CharField(max_length=20) price = models.FloatField() pub_date = models.DateField() class UserInfo(models.Model): username = models.CharField(max_length=32) email = models.EmailField(max_length=32)
name=models.CharField(max_length=20,verbose_name="姓名") 起别名
price=models.IntegerField("价格") # 起别名
如果后面继续增加表结构:python manage.py makemigrations
python manage.py migrate
3)pycharm中查看创建的表
4)单表内容的增删改
第一步:查看表字段
class Book(models.Model): name = models.CharField(max_length=20) price = models.FloatField() pub_date = models.DateField() author = models.CharField(max_length=32,null=False)
前端网页显示
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <style> * { margin: 0; padding: 0; } .head{ line-height: 40px; background-color: green; color: white; text-align: center; } </style> </head> <body> <div class="outer"> <div class="head">标题</div> <div class="content"> <a href="/addbook/">添加书籍</a> <a href="/update/">修改书籍</a> <a href="/delete/">删除书籍</a> <a href="/select/">查询书籍</a> </div> <div class="queryResult"> {% for book in book_list %} <div> <p>{{ book.name }} {{ book.author }} {{ book.price }}</p> </div> {% endfor %} </div> </div> </body> </html>
配置相应的路由
urlpatterns = [ url(r'^admin/', admin.site.urls), url(r'index/', views.index), url(r'^addbook/',views.addbook), url(r'^update/', views.update), url(r'^delete/', views.delete), url(r'^select/', views.select), ]
4.1)根据表字段执行添加内容
def addbook(request): # 第一种 # b = Book(name="python基础",price=99,author="egon",pub_date="2016-12-12") # b.save() # 第二种 Book.objects.create(name="python进阶",price=69,author="egon",pub_date="2017-02-12") # Book.objects.create(**dic) 用户输入的字段完全一样的情况下 return HttpResponse("添加成功")
4.2)更新修改表内容
def update(request): # 第一种,推荐使用,只对修改的字段赋值 Book.objects.filter(author="egon").update(price=998) # 第二种,如果在sqlite可能会出错,实现原理,无论其他字段改没改,都重新赋值 # b=Book.objects.get(author="oldboy") # b.price=120 # b.save() # print(b)#<QuerySet [<Book: Book object>]> # print(type(b)) return HttpResponse("更新成功")
4.3)删除表内容
def delete(request): Book.objects.filter(author="oldboy").delete() return HttpResponse("删除成功"
4.4)查看表内容
def select(request): # 第一种查询全部 book_list = Book.objects.all() # book_list = Book.objects.all()[:3] # 列表特性,获取前3条记录 # book_list = Book.objects.all()[::2] # book_list = Book.objects.all()[::-1] # book_list = Book.objects.filter(id=2) # 只要用filter取出来的就是集合 # book = Book.objects.first() # 获取第一个元素 # book = Book.objects.last() # 获取最后一个元素 # book = Book.objects.get(id=2) # 只能获取到1个,多条报错 # ret = Book.objects.filter(author="egon").values("name") # 查询到作者是egon的写的所有书名 # ret = Book.objects.filter(author="egon").values("name",'price') # 列表中的字典形式,获取到指定的字段内容 # ret = Book.objects.filter(author="egon").values_list("name", 'price') # 列表中的元组形式 book_list = Book.objects.exclude(author="egon").values("name",'price') # (排除)排除egon的内容 # values_list 该数据类型无法在前端调用的属性 # book_list = Book.objects.all().values("name").distinct() # 根据name字典去重 book_cont = Book.objects.all().values("name").distinct().count() # 确定有多少记录 return render(request,'index2.html',{"book_list":book_list})
查询归纳总结
# 查询相关API: # <1>filter(**kwargs): 它包含了与所给筛选条件相匹配的对象 # <2>all(): 查询所有结果 # <3>get(**kwargs): 返回与所给筛选条件相匹配的对象,返回结果有且只有一个,如果符合筛选条件的对象超过一个或者没有都会抛出错误。 #-----------下面的方法都是对查询的结果再进行处理:比如 objects.filter.values()-------- # <4>values(*field): 返回一个ValueQuerySet——一个特殊的QuerySet,运行后得到的并不是一系列 model的实例化对象,而是一个可迭代的字典序列 # <5>exclude(**kwargs): 它包含了与所给筛选条件不匹配的对象 # <6>order_by(*field): 对查询结果排序 # <7>reverse(): 对查询结果反向排序 # <8>distinct(): 从返回结果中剔除重复纪录 # <9>values_list(*field): 它与values()非常相似,它返回的是一个元组序列,values返回的是一个字典序列 # <10>count(): 返回数据库中匹配查询(QuerySet)的对象数量。 # <11>first(): 返回第一条记录 # <12>last(): 返回最后一条记录 # <13>exists(): 如果QuerySet包含数据,就返回True,否则返回False。
models.gamedb_sun.objects.all().order_by('id').reverse() 反转需要和 order_by联合使用
start = models.gamedb_sun.objects.filter(data='2019-02-10').first() end = models.gamedb_sun.objects.filter(data='2019-02-18').first() start = start.id end = end.id print(start,end) index_list = models.gamedb_sun.objects.filter(id__lt=end, id__gt=start)
4.5)万能的模糊查询之双下划线
def select(request): #万能的 __ # book_list=Book.objects.filter(price__gt=50).values("name","price") # 筛选出大于50的 book_list=Book.objects.filter(name__contains="P").values_list("name","price") # 筛选出name字段含有"P" # __icontains 不区分大小写。前面含"i",则不区分大小写 return render(request,'index2.html',{"book_list":book_list})
双下划线(__)之单表条件查询总结
models.Tb1.objects.filter(id__lt=10, id__gt=1) # 获取id大于1 且 小于10的值 models.Tb1.objects.filter(id__in=[11, 22, 33]) # 获取id等于11、22、33的数据 models.Tb1.objects.exclude(id__in=[11, 22, 33]) # not in models.Tb1.objects.filter(name__contains="ven") models.Tb1.objects.filter(name__icontains="ven") # icontains大小写不敏感 models.Tb1.objects.filter(id__range=[1, 2]) # 范围bettwen and startswith,istartswith, endswith, iendswith,
4.6)查看调用的sql语句
对于每次创建一个对象,想显示对应的raw sql,需要在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', }, } }
5)多表查询之一对多
class Book(models.Model): name=models.CharField(max_length=20) price=models.IntegerField() pub_date=models.DateField() publish=models.ForeignKey("Publish") authors=models.ManyToManyField("Author") def __str__(self): return self.name class Publish(models.Model): name=models.CharField(max_length=32) city=models.CharField(max_length=32) def __str__(self): return self.name
第一步查看表结构
app01_book
app01_publish
第一种:查询生成python的出版社的信息 # book_obj=Book.objects.get(name="python") # print(book_obj.name) # print(book_obj.pub_date) # # #一对多:book_obj.publish--------一定是一个对象 # print(book_obj.publish.name) # print(book_obj.publish.city) # print(type(book_obj.publish)) 第二种:查询记录(通过对象) 正向查询:A---> B正向:正向查按字段 book_obj = Book.objects.get(name="python") pub_obj=book_obj.publish -----》书籍对象对应的出版社对象 pub_obj.name 反向查询:B---> A反向:反向查按表名小写_set pub_obj = Publish.objects.filter(name = "人民出版社") pub_obj.book_set.all().values("name","price") 第三种:查询人民出版社出过的所有书籍名字和价格 #方式一: # pub_obj=Publish.objects.filter(name="人民出版社")[0] # ret=Book.objects.filter(publish=pub_obj).values("name","price") # print(ret) #方式二 # pub_obj = Publish.objects.filter(name="人民出版社")[0] # print(pub_obj.book_set.all().values("name","price")) #print(type(pub_obj.book_set.all())) #方式三 # ret=Book.objects.filter(publish__name="人民出版社").values("name","price") # print(ret)
6)多表操作之一对多的增删改查
class Book(models.Model): name=models.CharField(max_length=20) price=models.IntegerField() pub_date=models.DateField() publish=models.ForeignKey("Publish") # 创建的约束,约束条件下,默认生成的表字段加上 _id def __str__(self): return self.name class Publish(models.Model): name=models.CharField(max_length=32) city=models.CharField(max_length=32)
app01_publish
app01_book
6.1)一对多中增加表内容
方式一 Book.objects.create(name="linux运维",price=77,pub_date="2017-12-12",publish_id=2) 方式二 publish_obj=Publish.objects.filter(name="人民出版社")[0] # 找到人民出版社的id,赋值给book的publish Book.objects.create(name="GO",price=23,pub_date="2017-05-12",publish=publish_obj)
6.2)一对多中查询表内容
正常查询
#查询人民出版社出过的所有书籍名字和价格 方式一: pub_obj=Publish.objects.filter(name="人民出版社")[0] ret=Book.objects.filter(publish=pub_obj).values("name","price") print(ret) #方式二 pub_obj = Publish.objects.filter(name="人民出版社")[0] print(pub_obj.book_set.all().values("name","price")) print(type(pub_obj.book_set.all()))
__ 匹配多表查询。filter 和 __ ==》 跨表查询
ret=Book.objects.filter(publish__name="人民出版社").values("name","price") print(ret) #python这本书出版社的名字 ret2=Publish.objects.filter(book__name="python").values("name") print(ret2) ret3=Book.objects.filter(name="python").values("publish__name") print(ret3) ret4=Book.objects.filter(publish__city="北京").values("name") print(ret4) ret5=Book.objects.filter(pub_date__lt="2017-07-01",pub_date__gt="2017-01-01").values("publish__name") print(ret5)
7)多表操作之多对多
7.1)ManyToManyField自动创建第三张虚拟的关系表
class Book(models.Model): name=models.CharField(max_length=20) price=models.IntegerField() pub_date=models.DateField() publish=models.ForeignKey("Publish") authors=models.ManyToManyField("Author") # 会自动生成多对多的book_author的关系表 def __str__(self): return self.name class Publish(models.Model): name=models.CharField(max_length=32) city=models.CharField(max_length=32) def __str__(self): return self.name class Author(models.Model): name=models.CharField(max_length=32) age=models.IntegerField(default=20) def __str__(self): return self.name
基本的查询
book_obj=Book.objects.get(id=3) print(book_obj.authors.all()) print(type(book_obj.authors.all())) author_obj=Author.objects.get(id=2) print(author_obj.book_set.all())
增加关系的表操作
通过对象的方式绑定关系 增加一条记录book_author的关系记录 book_obj=Book.objects.get(id=4) author_obj=Author.objects.get(id=2) book_obj.authors.add(author_objs) # 第4本书的作者是2号作者 增加多条记录book_author的关系记录 book_obj=Book.objects.get(id=4) author_obj=Author.objects.all() book_obj.authors.add(*author_objs) 第4本书的作者是所有的作者搞的 解除某书与作者之间的关系 book_obj=Book.objects.get(id=4) author_obj=Author.objects.all() book_obj.authors.remove(*author_objs) 解除某书与作者的id关系 book_obj=Book.objects.get(id=3) author_obj=Author.objects.all() book_obj.authors.remove(2) # 指解除书的id为3的,作者为2的关系
对比真实表比较查询。真实表的创建在后面
#alex出过的书籍名称及价格,真实表 ret=Book.objects.filter(book_author__author__name="alex").values("name","price") print(ret) # ManyToManyField自动创建的虚拟表 ret2=Book.objects.filter(authors__name="alex").values("name","price","authors__name") print(ret2)
补充内容
from django.db import models class Classes(models.Model): """ 班级表,男 """ titile = models.CharField(max_length=32) m = models.ManyToManyField('Teachers',related_name='sssss') class Teachers(models.Model): """ 老师表,女 """ name = models.CharField (max_length=32) class Student(models.Model): """ 学生表 """ username = models.CharField(max_length=32) age = models.IntegerField() gender = models.BooleanField() cs = models.ForeignKey(Classes,related_name='ssss') # cs,cs_id 1 3班 ######################## 单表 ######################## # 增加 # Teachers.objects.create(name='root') # obj = Teachers(name='root') # obj.save() # 查 # Teachers.objects.all() # Teachers.objects.filter(id=1) # Teachers.objects.filter(id=1,name='root') # result = Teachers.objects.filter(id__gt=1) # [obj(id,name),] # result = Teachers.objects.filter(id__gt=1).first() # 删除 # Teachers.objects.filter(id=1).delete() # 改 # Teachers.objects.all().update(name='alex') # Teachers.objects.filter(id=1).update(name='alex') ######################## 一对多 ######################## """ 班级: id name 1 3班 2 6班 学生 id username age gender cs_id 1 东北 18 男 1 2 东北1 118 男 2 2 东北1 118 男 1 """ # 增加 # Student.objects.create(username='东北',age=18,gender='男',cs_id=1) # Student.objects.create(username='东北',age=18,gender='男',cs= Classes.objects.filter(id=1).first() ) # 查看 """ ret = Student.objects.all() # [] # [ obj(..),] # [ obj(1 东北 18 男 1),obj(2 东北1 118 男 2),obj(..),] for item in ret: print(item.id) print(item.username) print(item.age) print(item.gender) print(item.cs_id) print(item.cs.id) print(item.cs.name) """ # 删除 # Student.objects.filter(id=1).delete() # Student.objects.filter(cs_id=1).delete() # cid = input('请输入班级ID') # Student.objects.filter(cs_id=cid).delete() # cname = input('请输入班级名称') # Student.objects.filter(cs_id=cid).delete() # Student.objects.filter(cs__name=cname).delete() ######################## 多对多 ######################## # 多对多 """ 班级: id title 1 3班 2 4班 3 5班 老师: id title 1 Alex 2 老妖 3 瞎驴 4 Eric 老师班级关系表(类): id 班级id 老师id 1 1 2 2 1 3 4 2 2 5 2 3 6 2 4 7 1 5 # 增 obj = Classes.objects.filter(id=1).first() #1 3班 obj.m.add(2) obj.m.add([4,3]) # obj = Classes.objects.filter(id=2).first() #1 3班 # obj.m.add(2) # obj.m.add([4,3]) obj = Classes.objects.filter(id=1).first() #1 3班 # 删除 # obj.m.remove([4,3]) # 清空 obj.m.clear() # 重置 obj.m.set([2,3,5]) # 查第三张表 # 把3班的所有老师列举 obj = Classes.objects.filter(id=1).frist() obj.id obj.titile ret = obj.m.all() # 第三张表 # ret是一个 [ 老师1(id,name),obj(id,name) ] """
班级: id name 1 3班 2 6班 class School: name = models.CharField(max_length=32) class Classes(models.Model): """ 班级表,男 """ titile = models.CharField(max_length=32) # m = models.ManyToManyField('Teachers') # 多对多 # sch = models.ForeignKey(School) 老师: id title 1 Alex 2 老妖 3 瞎驴 4 Eric class Teachers(models.Model): """ 老师表,女 """ name = models.CharField (max_length=32) 学生 id username age gender cs_id 1 东北 18 男 1 2 东北1 118 男 2 2 东北1 118 男 1 class Student(models.Model): """ 学生表 """ username = models.CharField(max_length=32) age = models.IntegerField() gender = models.BooleanField() cs = models.ForeignKey(Classes) # 示例: - 所有学生的姓名以及其所在班级名称,QuerySet stu_list = Student.objects.all() select * from tb; [obj,obj,obj,obj] stu_list = Student.objects.all().values("id",'username') select id,username from tb; [{"id":1,'username':'xx'},{id:'',username:''}] stu_list = Student.objects.all().values_list("id",'username') [(1,'root'), (2,'alex')] stu_list = Student.objects.all().values('username',"cs__name") for row in stu_list: print(row['username'],row['cs__name']) stu_list = Student.objects.all().values('username',"cs__titile",“cs__fk__name”) - 找到3班的所有学生 Student.objects.filter(cs__name='3班') obj = Classes.objects.filter(name='3班').first()
7.2)聚合函数查询:aggregate(*args,**kwargs)
调用模块 from django.db.models import Avg,Min,Sum,Max,Count ret=Book.objects.all().aggregate(Avg("price")) ret=Book.objects.all().aggregate(Sum("price")) ret=Book.objects.filter(authors__name="alex").aggregate(Sum("price")) ret=Book.objects.filter(authors__name="alex").aggregate(alex_money=Sum("price")) ret=Book.objects.filter(authors__name="alex").aggregate(Count("name")) print(ret) # 每一个作者出过的书的总价。涉及了分组 ret1=Book.objects.values("authors__name") ret2=Book.objects.values("authors__name").annotate(Sum("price")) print(ret2) # 每个出版社出版的价格最低的书 ret=Publish.objects.values("name").annotate(abc=Min("book__price")) print(ret)
7.3)引入F查询和Q查询
引入F,Q 函数 from django.db.models import Q,F # 对数据进行加减,引入F Book.objects.all().update(price=F("price")+10) # 找到价格是87或者是GO的,条件或,引入 Q ret = Book.objects.filter(Q(price=87)|Q(name="GO")) # 找到不少GO的 ret = Book.objects.filter(^Q(name="GO")) # Q查询也关键字查询组合使用,但Q查询一定要写在前面 ret=Book.objects.filter(Q(name="GO"),price=87) print(ret)
7.4)ORM的querySet集合对象特性。可节约内存的方式
ret = Book.objects.filter(price=100) # 如果不使用ret,则不执行sql语句 for i in ret: print(i.price) if ret.exists(): # 仅仅是判断有没有值,不会把查询结果存在内存中 print("ok") 节省内存,变化成迭代器 ret=ret.iterator() print(ret) for i in ret: print(i.name)
7.5)models.py 创建第三张真实表的关系表
class Book(models.Model): name=models.CharField(max_length=20) price=models.IntegerField() pub_date=models.DateField() publish=models.ForeignKey("Publish") def __str__(self): return self.name class Publish(models.Model): name=models.CharField(max_length=32) city=models.CharField(max_length=32) def __str__(self): return self.name class Book_Author(models.Model): book=models.ForeignKey("Book") author=models.ForeignKey("Author") class Author(models.Model): name=models.CharField(max_length=32) age=models.IntegerField(default=20) def __str__(self): return self.name
表关系应用。虚拟表在上面
#创建第三张表 Book_Author.objects.create(book_id=2,author_id=2) # 通过id为2的书的作者 obj=Book.objects.get(id=2) print(obj.book_author_set.all()[0].author) #alex出过的书籍名称及价格 ret=Book.objects.filter(book_author__author__name="alex").values("name","price") print(ret)
8)模型中常用的字段类型参数
<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=19, decimal_places=10) # 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参数.
9)field 重要参数
<1> null : 数据库中字段是否可以为空 <2> blank: django的 Admin 中添加数据时是否可允许空值 <3> default:设定缺省值 <4> editable:如果为假,admin模式下将不能改写。缺省为真 <5> primary_key:设置主键,如果没有设置django创建表时会自动加上: id = meta.AutoField('ID', primary_key=True) primary_key=True implies blank=False, null=False and unique=True. Only one primary key is allowed on an object. <6> unique:数据唯一 <7> verbose_name Admin中字段的显示名称 <8> validator_list:有效性检查。非有效产生 django.core.validators.ValidationError 错误 <9> db_column,db_index 如果为真将为此字段创建索引 <10>choices:一个用来选择值的2维元组。第一个值是实际存储的值,第二个用来方便进行选择。 如SEX_CHOICES= (( ‘F’,'Female’),(‘M’,'Male’),) gender = models.CharField(max_length=2,choices = SEX_CHOICES)
10)修改默认存储时间。默认存储会有6位毫秒
查看源码文件 django/db/backends/mysql/base.py
class DatabaseWrapper(BaseDatabaseWrapper): vendor = 'mysql' display_name = 'MySQL' # This dictionary maps Field objects to their associated MySQL column # types, as strings. Column-type strings can contain format strings; they'll # be interpolated against the values of Field.__dict__ before being output. # If a column type is set to None, it won't be included in the output. data_types = { 'AutoField': 'integer AUTO_INCREMENT', 'BigAutoField': 'bigint AUTO_INCREMENT', 'BinaryField': 'longblob', 'BooleanField': 'bool', 'CharField': 'varchar(%(max_length)s)', 'DateField': 'date', 'DateTimeField': 'datetime(6)', 'DecimalField': 'numeric(%(max_digits)s, %(decimal_places)s)', 'DurationField': 'bigint', 'FileField': 'varchar(%(max_length)s)', 'FilePathField': 'varchar(%(max_length)s)', 'FloatField': 'double precision', 'IntegerField': 'integer', 'BigIntegerField': 'bigint', 'IPAddressField': 'char(15)', 'GenericIPAddressField': 'char(39)', 'NullBooleanField': 'bool', 'OneToOneField': 'integer', 'PositiveIntegerField': 'integer UNSIGNED', 'PositiveSmallIntegerField': 'smallint UNSIGNED', 'SlugField': 'varchar(%(max_length)s)', 'SmallIntegerField': 'smallint', 'TextField': 'longtext', 'TimeField': 'time(6)', 'UUIDField': 'char(32)', }
分析需要更改DateTimeField这个的字段显示
在models.py中更改添加如下数据
from django.db.backends.mysql.base import DatabaseWrapper DatabaseWrapper.data_types["DateTimeField"] = 'datetime' class Alarm(models.Model): id = models.AutoField(primary_key=True) rule_name = models.CharField(max_length=128) state = models.CharField(max_length=128) cluster = models.CharField(max_length=128) start_time = models.DateTimeField('保存日期',auto_now_add = True) end_time = models.DateTimeField('最后修改日期',auto_now = True) rule_group_name = models.CharField(max_length=128)
11)批量插入
class DemoView(APIView): def get(self, request): demolist = [] for age in range(1,200): demodict = {} demodict["name"] = "test" + str(age) demodict["age"] = age demolist.append(Demo(name='test%s' % str(age),age=age)) print(demolist) Demo.objects.bulk_create(demolist) return JsonResponse({"code": 200}, safe=False)
原文出处:https://www.cnblogs.com/yuanchenqi/articles/6083427.html