django备忘
引用:https://www.cnblogs.com/zjaiccn/p/14338994.html
文章目录
- 1.Django是什么
- 2.创建Django项目
- 3.模板初探
- 4.ORM的引出
- 5.ORM语句总结
- 6.Django Admin (组件)
- 7.定制Django admin
- 8.views 视图(views文件的操作)
Django(个人推荐, 如果项目较大 需要协同开发, 建议使用django这种重量级框架, 如果类似于纯api的后端应用建议使用 flask, 轻量小巧 , 麻雀虽小五脏俱全)
1.Django是什么
他是一个基于python语言的WEB框架
-
为什么使用Django
- 他是python中最大的框架集成很多api
- 他是全球第五大框架(代表作豆瓣)
- 适合开发工期短,效率高使用
-
Django的优势
- 开发效率高,功能强大
-
通过wsgi模块理解Django的工作集成原理
- 路由分发器通过写一个函数上传一个字典,如果传进来的environment.get('PATH_INFO')在字典中存在,就执行对应的函数,否则返回404f
-
wsgi是一种规范,wsgiref是基于wsgi规范开发的模块
- 虽然自己写web server比较的麻烦,但是我们也从中了解了web框架的本质
- 浏览器是socket客户端,网站是socket服务端
- wsgi是一种web server开发的规范,wsgiref实现了这个规范并在其内部实现了socket服务端
- 根据url的不同执行不同的函数 - 路由分发
- 函数 - 处理业务逻辑的进程
- 图案css js文件统一称为静态文件,需要读取内容直接返回给用户浏览器
- 虽然自己写web server比较的麻烦,但是我们也从中了解了web框架的本质
2.创建Django项目
-
django-admin.py startproject my_site 创建my_site项目
- 创建成功后会有几个默认的文件
- manage.py # 管理程序的文件,启动和结束等
- my_site #
- init.py
- settings.py # 程序的配置文件 - 数据库配置之类的
- urls.py # 程序的路由系统
- wsgi.py # 指定框架的wsgi
- 在my_site大项目下创建app每一个业务线都要有一个app
- 创建app django-amdin.py startapp app01
- ├── admin.py 数据库管理后台
├── apps.py django把项目和app 关联起来的一个文件
├── init.py
├── migrations 与数据库相关
│ └── init.py
├── models.py 数据库增删该查操作的文件
├── tests.py 单元测试
└── views.py 业务逻辑函数代码存放的位置
- 创建成功后会有几个默认的文件
-
第一次django请求
- 1.首先匹配路由,查找对应的url对应的关系,找到了就调用返回页面,否则404
- 2.业务函数,执行业务逻辑
- 3.返回数据给浏览器
启动django web服务器 python3 manage.py runserver 0.0.0.0:8000
retrun HttpResponse方法返回我们定义的数据
3.模板初探
- 1.配置settings DIRS
- 2.配置views.py return render(request,'form.html')
- MVC & MTV
- m model 模型 一般对数据库操作,数据的存取 models.py
- v views 视图 决定着如何展示数据 views.py
- c controller 控制器 负责处理用户交互的部分,控制器负责从视图读取数据,控制用户输入,并向模型发送数据. urls.py
Django是一个MTV框架,其框架模板上看起来和传统的MVC架构没有什么太大的区别.
Django将MVC中的视图进一步分解为Django视图和Django模板两个部分
- Django中的html文件就是模板 视图就是views.py
-
T 就是Templates 数据展示
在Django的MTV框架中MVC C控制器部分由Django框架的urlconf来实现代替
严格来说Django是MVTC C被实现替代了
urls.py文件中 re_path是使用正则匹配用户请求的url 主要配合动态路由
-
Django路由的匹配心法
-
Django 在2.0之后使用了新的语法path,不使用re_path
-
path('articles/<int:arg1>/<month:arg2>/<int:arg3>', views.kw)
-
str 字符串 除了/ 之外的任何字符串都能匹配
-
int 匹配任意数字
-
slug 匹配任意的**-**-**
-
uuid 匹配uuid格式的,特定场景下才会使用的到
-
path / + str 可以匹配到/
-
-
使用include管理app下的url
-
在顶级的urls.py文件中导入from django.urls import include
-
path('app01/',include('app01.urls')),
-
-
Django的模型(admin文件的操作)
- views中操作数据库
- 自己写sql语句的问题 - 有sql注入的风险,代码与sql写死在一起了,导致解耦性差,开发人员的sql水平层次不齐,导致性能可能会变差,开发效率低下
4.ORM的引出
-
ORM是什么?
- 对象关系映射,他的实质就是将关系数据库中的业务数据用对象的形式表示出来,并通过面向对象的方式将这些对象组织起来,实现系统业务逻辑过程
- ORM中最重要的概念就是映射,通过这种映射可以使业务对象与数据库分离,从面向对象来说,数据库不应该和业务逻辑绑定到一起,ORM则起到这样的分离作用,使数据库层透明,开发人员真正的面向对象.
-
ORM的作用
- 实现了代码与数据库操作的解耦
- 不需要自己写原生的sql,提高了开发效率
- 有效的防止了sql注入
- 缺点
- 牺牲性能 - 将对象转换成原生的sql
- 复杂语句难以实现
-
ORM映射字段的语法
-
AutoField (设置自增)
-
BigAutoField (设置更大的自增)
-
BigIntegerField (更大的整数)
-
BinaryField (二进制的数据)
-
BooleanField (布尔类型的数据)
-
CharField (字符串类型的数据)
-
DateField (年与日时间类型)
-
DataTimeField(精确到时分秒的时间类型)
-
DecimalField ()
-
DurationField()
-
EmailField(邮箱类型)
-
FileField(存储文件的类型)
-
FloatField(浮点数类型)
-
ImageField(图片类型)
-
IntegerField(整数类型)
-
GenericIPAddressField(ipv4地址类型)
-
NullBooleanField (允许boolean类型为空)
-
TextField(大的文本)
-
ForeignKey(外键关联)
-
ManyToManyField(多对多)
-
OneToOneField(1对1)
-
-
将models文件中的类同步到mysql数据库中(必须要注意models文件中的外键和多对多要一一对应)
-
在Django官网找到数据库的配置https://docs.djangoproject.com/en/3.0/ref/settings/#databases 写到settings文件当中
-
在项目下的init.py文件中写入
-
import pymysql pymysql.version_info = (1, 3, 13,"final",0) pymysql.install_as_MySQLdb()
-
创建数据库mysql> create database blogdatabase charset utf8;
-
在settings文件中设置INSTALLED_APPS 加上app的名字
-
使用Django数据库的同步工具migrations
- 1.生成同步文件 python manage.py makemigrations
- 2.同步数据库 python manage.py migrate
-
-
使用ORM映射插入数据 首先 python manage.py shell
-
普通创建
>>> models.Account.objects.create( >>> ... username = 'jeke', >>> ... email = '123@163.com', >>> ... password = '123', >>> ... )
-
外键关联创建
>>> o = models.Article( >>> ... title = '我是Peter', >>> ... content = 'xixi', >>> ... pub_data = '2020-6-11') >>> o >>> <Article: Article object (None)> >>> o.account_id = 1 > >>> o.save()
-
多对多的创建数据
- 先创建完对象在关联o.tags.set([id,id]) 这是覆盖性设置
- o.tags.add(id,id) 这是添加
-
-
ORM对数据进行查询(后来找到的查询语法https://www.cnblogs.com/ls1997/p/10955402.html)
-
models.Account.objects.all() ==> select *
-
models.Account.objects.filter(id=1) ==> select * where id=1
-
models.Account.objects.filter(id__gt=1) ==> where id > 1
-
models.Account.objects.filter(id__gt=1,password='111') ==> where id >1 and password ='111';
-
models.Account.objects.filter(password__startswith=1) ==> where password like '1%'
-
models.Account.objects.filter(username__contains='zj') ==> 只要username包含大小写的zj
-
models.Account.objects.filter(username__icontains='zj') ==> 只能匹配到小写的zj
-
models.Account.objects.filter(id__in=[1,2]) ==> where id in (1,2)
-
models.Account.objects.filter(username__endswith='j') ==> where username like '%j'
-
日期的待补充
-
filter正则表达式
- models.Account.objects.filter(username__regex=r'(zj|j)$') 以zj或者j结尾
- models.Account.objects.filter(username__iregex=r'(zj|j)$') 加上i就是大小写不敏感都匹配
-
上边拿到的都是queryset的对象,不是数据,想要拿到数据可以使用很多方法
>>> a = models.Account.objects.filter(username__regex=r'(zj|j)$') >>> b = a.values() >>> b.values('id').order_by('id') #升序 <QuerySet [{'id': 2}, {'id': 3}]> >>> b.values('id').order_by('-id') <QuerySet [{'id': 3}, {'id': 2}]> #降序 >>> *想要用reverse 必须要用先order_by排序* >>> b.values('id').order_by('-id').reverse() #翻转 <QuerySet [{'id': 2}, {'id': 3}]> >>> b.values('id').order_by('id').reverse().first() #取最后一个值,先翻转在取第一个 {'id': 3}
-
5.ORM语句总结
-
a = models.Account.objects.get(id=1) 精确查询某一字段 #返回的是真实的对象了,不是queryset对象了
直接调用a.id a.username 即可
-
models.Account.objects.exclude(id=1)
<QuerySet [<Account: Account object (2)>, <Account: Account object (3)>]>
get 返回一个对象,没有或者多个会报错,不常用但是要不filter查询速率快
filter 返回多个对象
all 返回所有数据
exclude 排除符合匹配条件的数据,返回其他的数据
- 修改和删除操作
- 修改全部
>>> models.Account.objects.exclude(id=1).update(password='1234656') #批量修改只要是id不等于1的密码都改成123456
- 单条修改(先get在赋值后保存)
>>> a = models.Account.objects.get(id=1)
>>> a.password = '123456789'
>>> a.save()
- 批量删除,关联的表的数据也会删除或者变成设置的默认的
>>> models.Account.objects.get(password='123456').delete()
- 单条删除
>>> a = models.Account.objects.get(id=1)
>>> a.delete()
外键关联操作(模块创建)
正向外键关联(在有关联字段的表中查询)
>>> a = models.Article.objects.create(title = 'hahahaha322332', content = '阿光高你刚42151啊方法',account_id = 8 ,pub_data = '2020-06-12')
>>> a.account.id # a 定义的是Article的数据,但是可以通过外键关联到Account 查询到Account的数据
反向外键关联(无关联字段的表中查询, ORM会自动的帮助我们创建一个表)
>>> obj = models.Account.objects.all()[0]
>>> obj.article_set.all()
<QuerySet [<Article: Article object (6)>]>
>>> obj.article_set.all().values()
<QuerySet [{'id': 6, 'title': 'hahahaha', 'content': '阿光高你刚啊方法', 'account_id': 4, 'pub_data': datetime.date(2020, 6, 12)}]>
多对多关联
>>> a.tags.all()
>>> t = models.tag.objects.all()[1]
>>> t.article_set.all()
6.Django Admin (组件)
admin 是Django自带的让你用来进行数据库管理的web app
提供了很多定制化的功能,你甚至可以用它来进行公司内部的内容管理
首先创建登录的用户 >> python3 manage.py createsuperuser
如果app01想要被管理的话,必须授权允许管理admin.py文件写入下面的内容
from django.contrib import admin
from app01 import models
# Register your models here.
admin.site.register(models.Account)
admin.site.register(models.Article)
admin.site.register(models.Tag)
开启Django >> python3 manage.py runserver 0.0.0.0:8000
打开localhost:8000/admin 就可以看到对应的数据库进行操作了
7.定制Django admin
from django.contrib import admin
from app01 import models
class AccountAdmin(admin.ModelAdmin):
list_display = ('username', 'email', 'signature') # 显示这三个字段
search_fields = ('username', 'email','signature') # 加入搜索按钮
list_filter = ('email', ) # 过滤, 针对重复的字段过滤
list_per_page = 2 # 设置分页
# list_display_links = ('email',)
class ArticleAdmin(admin.ModelAdmin):
list_display = ('title', 'content', 'account', 'pub_data')
list_filter = ('account', 'pub_data')
search_fielshituds = ('title',)
fields = ('title', 'content', ('pub_data', 'account', 'tags')) # 设置admin修改创建页面可修改的数据
exclude = ('account',) # 排除不显示一些字段
date_hierarchy = 'pub_data' # 按照时间的分组(只能用时间)
fieldsets = (
('文章基本信息', {
'fields': ['title', 'content'],
},
),
('高级选项', {
'fields': ['account', 'tags', 'pub_data'],
'classes': ('collapse',), # 让这个高级选项变成有收缩折叠功能
}
)
)
filter_horizontal = ('tags',) # 只能针对多对多
filter_vertical = ('tags',)
radio_fields = {'account': admin.VERTICAL} # 将下拉框变成按钮以供选择
autocomplete_fields = ['account',]
readonly_fields = ('title',) # 设置只读字段
admin.site.register(models.Account,AccountAdmin)
admin.site.register(models.Article,ArticleAdmin)
admin.site.register(models.Tag)
-
自定义Admin字段
在models文件中写入
def get_comment(self): return 10
再在admin对应的库中加上list_display = ('get_comment',) 字段
-
自定义字段名 在,models中修改
-
signature = models.CharField("签名", max_length=255, null=True) # null允许值为空,签名
-
自定义表名 在models文件中类中加入
class Meta: # verbose_name = "用户列表" # 针对英文的 verbose_name_plural = '用户列表' # 针对中文的
-
8.views 视图(views文件的操作)
-
视图中的字段抛开讲解
-
HttpRequest对象属性
- 他封装了本次请求所涉及的用户浏览器端数据,服务器端数据等,在views里可以通过request对象来调取相应的属性
- request.scheme ==> 查看是https 协议还是http
- request.path == > 返回的是当前请求的url
- request.method ==> 查看获取网页的方法 post get put delete
- request.content_type ==> 返回mime的类型
- request.GET ==> 打印网页GET请求的参数
- request.POST ==> 打印网页POST请求的参数
- request.COOKIE ==> 获取浏览器的cookie数据
- request.FILES == > 拿到通过前端页面上传来的文件,放到内存当中
- request.POST.get("test_f") ==> 拿到选择文件的文件名
- request.META ==> 返回所有的请求头
-
除了属性HttpRequest的方法
- request.get_host() ==> 返回网站服务器地址,example: '127.0.0.1':'8000'
- request.get_port() ==> 返回服务器主机端口
- request.get_full_path() ==> 返回请求的路径
- request.build_absolute_uri(locaiton) ==> 返回请求完整的url
- request.is_srcure() ==> 判断他是不是https
- request.is_ajax() ==> 判断是否是ajax请求
-
Httpresponse(content_type格式参考手册https://www.w3school.com.cn/media/media_mimeref.asp)
-
设置下载文件的方法
def download(request): f = open("static_data/15s第三方软件设备适配情况.xlsx", 'rb') res = HttpResponse(f.read(),content_type='application/vnd.ms-excel') # 设置返回的内容格式为excel文档格式 res['Content-Disposition'] = 'attachment; filename ="15s.xlsx"' # 设置用户请求的时候下载下来的是一个attachement附件和文件名 return res
-
设置重定向
def redirect(request): return HttpResponseRedirect("/app01/download")
-
-
CBV(class base view) 类视图
- 使用类的方式来定义视图,提高代码的可复用性,还可以加入判断条件,还有继承
from django.views import view
class TestView(View):
def get(self,request):
return HttpResponse("测试get请求自动的使用这个get()函数")
def post(self,request):
return HttpResponse("测试post")
在url 定义的时候加入as.view()方法
path('class_view',view.TestView.as_view())