signed

QiShunwang

“诚信为本、客户至上”

Django Full Coverage

2021/1/28 12:12:33   来源:

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文件统一称为静态文件,需要读取内容直接返回给用户浏览器

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())

很久没有整理之前的笔记了.... 😢