Django使用总结

2019-06-02 18:15:09阅读 93评论 0

1.模型

需要在models.py创建类,并且该类需要继承modes.Model,1个类就是1个表
ORM是通过使用描述对象和数据库之间映射的元数据,自动生成sql语句,将程序中的对象自动保存到关系数据库中
优点:隐藏数据库访问细节,提高开发效率,提高可移植性,提高安全性
缺点:执行效率低,对复杂sql无能为力

1)字段类型

CharField(max_length=字符长度) 字符串,默认表单样式为TextInput
TextField 大文本字段,一般超过4000使用,默认表单为Textarea
IntegerField 整数
FloatField 用python的float实例表示浮点数
BlooleanField 布尔型 True/Flase 字段 此字段默认表单是CheckboxInput
DateTimeField 日期+时间

2)字段约束属性

null Django将空值以null形式存储到数据库,默认false
db.index 值为true,则在表中为此字段创建索引
primary_key 若为true ,则字段成为模型主键字段
unique 如果为True 字段在表中必须有唯一值
default 设置字段默认值
auto_now_add: 增加记录时的时间
auto_now: 更新当前记录的时间

3)字段关系

ForeignKey 一对多,将字段定义在多的类中(on_delete=models.CASCADE)
ManyToManyField 多对多,将字段定义在两端中
OneToOneField 一对多,将字段定义在任意一端

4)查询(views里操作)

(1)查询

filter(id=1)返回queryset对象列表(每一行1对应一个对象)
get(id=1)返回查询到的第一个对象结果
values() 接收可选的位置参数fields,返回字典列表 values_list(fields, flat=False)返回元祖列表
distinct()去重,和values()合用
内部限制参数(filter函数):
contains是否包含,大小写敏感
startswith以value开头,大小写敏感
endwith以value结尾,大小写敏感
in是否包含在范围内
gt 大于
gte 大于等于
lt 小于
lte 小于等于
时间:
year month day week_day hour minute second
filter(lastTime__year=2017)
外部限制参数(filter函数):
order_by('date')按照date排序,默认正序,'-data'表示倒序

(2)一对多、多对多查询
    student1=models.student.objects.values('name','grade__name','courses__name')  
    for item in student1:  
                print(item)

在filter函数的参数里,外键字段__外键表的字段(如果双下划线对应的外键表是多对多表,如courses_name,结果如下)

    {'name': '张欢', 'grade__name': '一班', 'courses__name': '心理学'}  
    {'name': '小马', 'grade__name': '二班', 'courses__name': '心理学'}  
    {'name': '富二代', 'grade__name': '二班', 'courses__name': '心理学'}  
    {'name': '张欢', 'grade__name': '一班', 'courses__name': '日语'}  
    {'name': 'sylvester', 'grade__name': '一班', 'courses__name': '日语'}  
    {'name': '小黄', 'grade__name': '二班', 'courses__name': '日语'}  
    {'name': '小马', 'grade__name': '二班', 'courses__name': '摄影'}  
    {'name': '小黄', 'grade__name': '二班', 'courses__name': '摄影'}

备注:如果当前操作的表内没有字段为外键,但该表是其他表的外键,可用_set反向查找将此表设为外键的表

5)汇总操作

使用前需要导入from dango.db.models import Max,Avg,F,Q,Min,Count,Sum
分类:Avg Count Max Min sum
(1)聚合函数aggregate()(单一分组)
是QuerySet
的一个终止子句,意思是说,它返回一个包含一些键值对的字典。键的名称是聚合值的标识符,值是计算出来的聚合值。键的名称是按照字段和聚合函数的名称自动生成出来的

    result=models.student.objects.all()  
            for item in result:  
                print(item.name)  
                print(item.achievement_set.all().aggregate(Avg('mark')))

(2)分组聚合(为调用的QuerySet中每一个对象都生成一个独立的统计值,即每个对象就是一个分组 )

    final=models.student.objects.all().annotate(count=Count('courses__id'))  
            for item in final:  
                print(item.count)

6)增、改、删操作

(1)增

    models.UserInfo.objects.create(user='yangmv',pwd='123456')  
    #或者  
    obj = models.UserInfo(user='yangmv',pwd='123456')  
    obj.save()

多对多

    obj = models.Author.objects.get(id=1)  
    obj.add(*[1,2])

(2)改

    models.UserInfo.objects.filter(user='yangmv').update(pwd='520')

    #或者  
    obj = models.UserInfo.objects.get(user='yangmv')  
    obj.pwd = '520'  
    obj.save()

多对多

    obj = models.Author.objects.get(id=1)  
    obj.set([1,2])

(3)删

    models.UserInfo.objects.filter(user='yangmv').delete()

多对多

    obj = models.Author.objects.get(id=1)  
    obj.clear()

7)其他操作

(1)F查询
表内两个字段进行比较

    f=models.student.objects.filter(id__gt=F('grade'))  
            for item in f:  
                print(item.id,item.grade.id)

(2)Q查询
可以组合& 和| 操作符以及使用括号进行分组来编写任意复杂的Q 对象。同时,Q 对象可以使用~ 操作符取反,这允许组合正常的查询和取反(NOT) 查询

    q=models.student.objects.filter(Q(id__gt=1)&~Q(id=2))  
            for item in q:  
                print(item.id)

(3)事务操作

    from django.db import transaction  
    with transaction.atomic():  
            模型操作

2.模板

1)模板继承

父模板包含公共部分,子自定义部分。子模版继承父模板后,子模版将复制父模板,并且子自定义部分可对其进行重载
继承
{%extends 'XXX,html'%}
子自定义部分
{%block 自定义名%}
{%endblock%}

2)加载静态文件

{% load static %} 或者 {% load staticfiles %}
{% static ‘x/x/x’ %}

3)变量渲染

{{变量名}},变量可以是一切对象,用'.'可取到其属性
特殊变量{{csrf_token}},防止跨站伪请求,亦可用{%csrf_token%}

4)常用过滤器

{{value|过滤器}}, 作用:在变量显示前修改
(1){{value|safe}}信任变量内的html内容,允许其渲染
(2){{ value | length }}返回value的长度
(3){{ dateVal | date: ‘y-m-d hⓂ️s’ }}根据制定格式转换日期为字符串

5)自定义过滤器

(1)创建
<1>在当前app下创建templatetags文件夹,并在里面创建任意py文件(my_tags)
<2>在文件内定义过滤器

    from django import template  
    from django.utils.safestring import mark_safe  
    #register的名字是固定的,不可改变  
    register=template.Library()   
    #filter  
    @register.filter  
    def filer_multi(v1,v2):  
        return v1*v2  
    #simple_tag  
    @register.simple_tag  
    def tag_multi(v1,v2):

(2)模板中调用

    {% load my_tags %}  
    <!filer调用方式:>  
    <h1>{{ num|filer_multi:22  }}</h1>  
    <!simple_tag调用方式:>  
    <h1>{% tag_multi num 5 %}</h1>

(3)simple_tag和filter区别
<1>调用方式区别
filter调用格式: {{ obj |filter:param }}
simple_tag调用格式: {% filter param obj %}
<2>参数数量区别
filter最多只支持两个参数
simple_tag支持多个参数
<3>filter可以支持if、for等内置函数语句,simple_tag无法支持if、for等内置函数语句

    {% if num|filer_multi:5 > 10 %}  
        <h1>数值大于10</h1>  
        {% elif num|filer_multi:5 < 10 %}  
        <h1>数值小于10</h1>  
        {% else %}  
        <h1>数值等于10</h1>  
    {% endif %}

6)流程控制
(1)判断
{%if 判断语句%}
{%endif%}
(2)判断相等
{% ifequal value1 value2 %}
{%endifequal%}
(3)for循环
{% for 变量 in 列表 %}
{% empty %}
{% endfor %}
<4>url反向解析
{% url ‘namespace:name’链接中的参数%}

3.视图

1)CBV
urls.py中

    url(r'^login.html$', views.Login.as_view()),

views.py中

    from django.views import View    这一行必须写上  
    class Login(View):  
        def dispatch(self, request, *args, **kwargs):#请求进来会先执行该方法  
            print('before')  
            obj = super(Login,self).dispatch(request, *args, **kwargs)  
            print('after')  
            return obj  
        def get(self,request):  
            return render(request,'login.html')  
        def post(self,request):  
            print(request.POST.get('user'))  
            return HttpResponse('Login.post')

2)request
(1)request.body
(2)request.FILES
FILES 只有在请求的方法为POST 且提交的

带有enctype="multipart/form-data"
的情况下才会包含数据。否则,FILES 将为一个空的类似于字典的对象。
req.FILES['file1'].name获取文件名(上传时input的name是file1)
req.FILES['file1'].chunks()获取文件,该对象是一个生成器

    def get_file(req):  
        name=req.FILES['file1'].name#获取文件名  
        dirs=os.path.join(os.getcwd(),'uploadfiles',name)#设置文件保存路径  
        with open(dirs,"wb") as f:  
            for item in req.FILES['file1'].chunks():  
                f.write(item)  
        return HttpResponse('all done')

3)response
(1)Httpresponse()
(2)render()
(3)redirect()

4.路由

1)path

from django.urls import path,re_path  
from app01 import views as app01  
urlpattrerns=[  
path('article/<int:id>',app01.article),#使用转换器  
re_path('articles/(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/', views.month_archive),#使用正则  
]

转化器:
str,匹配除了路径分隔符(/)之外的非空字符串,这是默认的形式
int,匹配正整数,包含0
slug,匹配字母、数字以及横杠、下划线组成的字符串
uuid,匹配格式化的uuid,如 075194d3-6885-417e-a8a8-6c931e272f00
path,匹配任何非空字符串,包含了路径分隔符

2)路由分发

一个django项目中包含很多子项目(app),每个子项目需要有自己的路由,结合命名空间以实现路由分发。一个请求过来,由一级路由进行识别时哪一个app的请求,并转发到app,再由app将请求分配给视图函数。
一级路由

    from django.contrib import admin  
    from django.urls import path,re_path,include

    urlpatterns = [  
        path('admin/', admin.site.urls),  
        re_path(r'^app01/',include(('app01.urls','app01'))),#根据url进行分发,并为二级路由分配命名空间,便于url反向解析  
    ]

二级路由

    from django.urls import path  
    from app01 import views as app01  

    urlpatterns = [  
        path('student',app01.student),  
        path('achievement/<int:id>',app01.achievement),  
        path('choosecourses/<int:student_id>',app01.choosecourses,name='courses'),#分发到视图函数,并为该url命名,便于反向解析  
    ]

还没有评论,来说两句吧