美文网首页
2019-03-26 Django大纲

2019-03-26 Django大纲

作者: woming | 来源:发表于2019-03-26 17:15 被阅读0次

Django

虚拟环境

创建:virtualenv --no-site-packages -p python.exe的路径 环境名

安装与使用

安装:pip install django==2.1.7

创建Django项目:django-admin startproject 项目名

创建django应用:python manage.py startapp 应用名

启动,修改IP和端口

  • 修改端口:python manage.py runserver 端口号

  • 修改IP和端口:python manage.py runserver IP:端口号

数据库简单配置与迁移

  • 修改settings.py文件中DATABASE的数据:NAME,USER,PASSWORD,HOST,PORT,OPTIONS

  • 不管用不用,都必须迁移默认的模型 迁移django默认提供的模型:python manage.py migrate

管理后台

  • 访问:IP:端口/admin/

  • 创建账号:python manage.py createsuperuser

模型

迁移

  • 生成迁移文件: python manage.py makemigrations

  • 执行迁移文件:python manage.py migrate

  • 注意:当第一次迁移Django默认提供的表时,直接执行migrate命令即可

模型定义

  • 字段定义

    • IntegerField:整型字段

    • CharField:字符串

    • BooleanField:布尔值

    • DateTimeField:年月日时分秒字段

    • DateField:年月日

    • TimeField:时间戳

    • ImageField:图片

    • FloatField:浮点数

    • DecimalField:浮点数,指定了长度的浮点数

    • TextField:文本,textarea

    • AutoField:自增字段,不用定义

  • 约束定义

    • max_length:最大长度

    • min_length:最小长度

    • unique:是否唯一

    • null:是否为空

    • default:默认值

    • auto_now_add和auto_now:互斥

模型操作

    • 对象.save()

    • 模型.objects.create(字段1=值1,字段2=值2,...)

    • 对象.delete()

    • 模型.objects.filter().delete()

    • 修改的对象.save()

    • 模型.objects.filter().update(字段1=值1,字段2=值2,...)

    • all():queryset结果

    • first():取结果中第一个对象

    • last():取结果中最后一个对象

    • 模型.objects.filter(字段='值')

    • 模型.objects.get(条件)

      • 条件必须成立

      • 查询结果只有一个

    • exclude(条件):过滤不满足条件的信息

    • count():查询结果的个数

    • values('字段'):将对象的内容序列化成字典/json

    • order_by('字段')

      • 升序:order_by('字段')

      • 降序:order_by('-字段')

    • contains:包含

      • 模型.objects.filter(字段__contains='值')
    • startswith:以什么开头

    • endswith:以什么结尾

    • 大小于

      • 大于,大于等于:gt,gte

      • 小于,小于等于:lt, lte

    • aggregate:聚合

      • Avg, Sum, Count, Max, Min
    • F:对比两个属性字段,可以进行加减算法

      • 模型.objects.filter(字段1__gt=F('字段2'))
    • Q:用于与或非

      • 或:Q(条件1) | Q(条件2)

      • 非:~Q(条件1)

模型关系

一对一

  • OneToOneField(关联模型)

  • 模型定义

    class A(): id = models.IntegerField()

    class B(): aa = models.OneToOneField(A, related_name='cc')

    已知:A对象a,查询B对象 related_name没定义时: a.b related_name已定义时: a.cc

    已知:B对象b,查询A对象 b.aa

  • 注意:OneToOneField定义的字段可以写在关联模型的任意一方

一对多

  • ForeignKey(关联模型)

  • 模型定义

    class A(): id

    class B(): aa = ForeignKey(A, related_name='cc')

    已知:A对象a,查询B对象 related_name没定义时: a.b_set.all() related_name已定义时: a.cc.all()

    已知:B对象b,查询A对象 b.aa

  • 注意:ForeignKey定义的字段表示多的对方,因此只能放在'多'的模型中

多对多

  • ManyToManyField(关联模型):会自动生成中间表

  • 模型定义

    class A(): id

    class B(): aa = ManyToMany(A, related_name='cc')

    已知:A对象a,查询B对象 related_name没定义时: a.b_set.all()

    <pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="" cid="n198" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit;">related_name已定义时:
    a.cc.all()</pre>

    已知:B对象b,查询A对象 b.aa.all()

  • 注意:ManyToMany定义的字段可以写在关联模型的任意一方

  • 中间表的添加:add()、删除:remove()

字段中的on_delete参数值

  • models.CASCADE: 表示主键所在行的数据被删,外键所在行的数据也会被删,是完全关联在一起的

  • models.PROTECT: 表示主键作为外键存在别的表中时,不让删除主键的数据

  • models.SET_NULL: 表示主键删除,外键置空

模板

父模板:用于挖坑{% block name %} {% endblock %}

子模板:负责继承父模板后,进行填坑

标签:{% 标签 %}

  • {% extends '父模板' %}

  • {% block name %} {% endblock %}

  • {% if 条件 %} {% else %} {% endif %}

  • {% ifequal 变量 值 %} {% endifequal %}

  • {% for i in [] %} {% endfor %}

  • 解析静态文件地址: {% static 'css/xxx.css' %} 继承模板的时候,要有: {% load static %}

  • 解析路由地址: {% url 'user:index' %}

变量:{{ 变量名 }}

  • {{ forloop.counter }}

  • {{ forloop.counter0 }}

  • {{ forloop.revcounter }}

  • {{ forloop.revcounter1 }}

  • {{ forloop.first }}

  • {{ forloop.last }}

  • {{ stu.course.all }}:通过学生查询所有的课程信息

  • {{ stu.course.下标 }}

过滤器

  • 定义:使用管道符 '|'

路由规则

path

re_path

  • /(\d+)/(\w+)/

  • (?P<参数名>\d+)

include

urlpatterns = [ path('admin/', admin.site.urls), # 包含 # TODO:Django2.0以下写法, path('goods/', include('goods.urls')), path('app/', include('app.urls')) ]

  • 拆分路由地址,将不同应用的URL文件进行拆分

请求与响应

请求

  • method:判断请求方式,主要GET/POST

  • path:获取访问的路由地址

  • FILES:获取图片或文件的信息

  • GET:获取get请求方式的数据

    • get()

    • getlist()

  • POST:获取post请求方式的数据

  • COOKIES:cookie内容

  • session:存储在服务端的数据

响应

  • 跳转:HttpResponseRedirect()

    • 无参

      • HttpResponseRedirect(reverse('namespace:name'))
    • 有参

      • HttpResponseRedirect(reverse('namespace:name', kwargs={'参数名': '值'}))

      • HttpResponseRedirect(reverse('namespace:name', args=(值, )))

    • 页面反向解析

      • {% url 'namespace:name' 值1 值2 值3 ... %}
  • JsonResponse():响应json格式的数据

  • HttpResponse(字符串)

  • render(页面)

用户USER

使用django自带的USER模块

  • 注册:User.objects.create_user()

  • 校验:user = auth.authenticate(username, password)

  • 登录:auth.login(request, user)

  • 退出:auth.logout(requset)

  • 装饰器:login_required() 要配合在setting里面设置才有用: LOGIN_URL = '/user/login/'

自定义USER模块

  • 登录:request.session['user_id'] = user.id 添加键值对的时候,同时会把数据库中创建的session_key传给浏览器

  • 退出

    • request.session.flush() 同时删除数据库和浏览器中的session

    • request.session.delete(session_key) 删除数据库中对应的session记录

    • del request.session['user_id'] 删除数据库中之前添加的键值对,相当于删除浏览器识别session的唯一标识

  • 装饰器

    from django.http import HttpResponseRedirect from django.urls import reverse

    from user.models import MyUser

    def is_login(func):

    <pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="" cid="n352" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit;">def check(request, *args, **kwargs):

    登录的校验

    if 'user_id' in request.session:
    user = MyUser.objects.get(pk=request.session['user_id'])
    request.user = user
    return func(request, *args, **kwargs)
    else:
    return HttpResponseRedirect(reverse('user:my_login'))

    return check</pre>

中间件MIDDLEWARE

process_request(self, request):请求进来时直接进行拦截(应用场景:登录校验)

process_view(self, request, view_func, view_args, view_kwargs):调用view方法之前进行拦截调用

process_exception(self, request, exception):不主动调用,只有出现异常时才执行

process_response(self, response):最后响应浏览器时才调用

process_template_response():没有应用场景

执行顺序

  • 中间件按照排列顺序,从上往下依次执行process_request(), 如果返回None表示继续访问中间件或者方法, 如果return HttpResponse() 表示直接响应内容给浏览器

  • process_request()执行完毕后,从上往下执行process_view()

  • 前面的方法没有返回响应时,从下往上执行process_response()

文件上传

安装:pip install pillow

模型中定义字段:

icon = models.ImageField(upload_to='upload')

设置media文件夹路径:

MEDIA_URL = 'media' MEDIA_ROOT = os.path.join(BASE_DIR, 'media')

展示图片需要在工程目录的urls.py文件中指定静态文件路由:

static(MEDIA_URL, document_root=MEDIA_ROOT)

展示图片:

前端中定义属性<form enctype='multipart/form-data'>

表单验证

定义

class UserForm(forms.Form):
forms.CharField
forms.IntegerField
forms.ImageField

def clean(self):
    # 自动调用
    return self.cleaned_data

def clean_字段(self):
    # 校验指定字段
    return self.cleaend_data

forms = UserForm(request.POST, request.FILES)

验证:form.is_valid()

验证错误信息:form.errors

分页

from django.core.paginator import Paginator

paginator = Paginator(所有数据,条数)

  • 查看总页数:paginator.num_pages

  • 获取某一页的数据: page_data = paginator.page(页码)

  • paginator.page_range:相当于range(1,总页码数)

page_data = paginator.page(页码)

越界会报错

  • page_data.has_next():是否有下一页

  • page_data.has_previous:是否有上一页

  • page_data.next_page_number:下一页页码

  • page_data.previous_page_number:上一页页码

  • page_data.paginator:获取paginator对象

权限

RBAC

用户表--权限表--角色表:

都是多对多关联关系

用户和权限:user_permissions字段

用户和角色:groups字段

角色和权限:permissions字段

权限列表

  • 1.通过用户查询权限表

  • 2.通过用户查询角色,角色查询权限

权限获取

  • 获取所有权限:包括用户对应角色权限和用户对应权限表,user.get_all_permissions()

  • 获取用户组权限:user.get_group_permissions()

权限校验装饰器

  • @permission_required('应用名.权限名')

模板中

  • 解析当前用户的权限,是个集合: {{ perms.user }}:{'应用名.权限名'}

  • {% if perms.user.add_users %}

相关文章

网友评论

      本文标题:2019-03-26 Django大纲

      本文链接:https://www.haomeiwen.com/subject/lmdnvqtx.html