Django笔记

论坛 期权论坛 脚本     
匿名技术用户   2021-1-6 12:20   45   0

目录

MVC设计模式

MTV设计模式

安装

基本操作

设计表结构

配置mysql

创建应用:

激活应用:

定义模型:

在数据库中生成数据表:

测试数据操作:

启动服务器:

Admin站点管理:

使用装饰器完成注册:

视图的基本使用

模板的基本使用:

需求:点击班级,显示对应班级的所有学生

模型:

关系:

创建模型类:

元选项:

模型成员:

模型查询:


MVC设计模式

优点:降低各功能模块之间的耦合性,方便变更,更容易重构代码,最大程度上实现代码的重用

MTV设计模式

本质上与MVC没有差别,也是各组件之间为了保持松耦合关系,只是定义上有些许不同

编程模式:Model(模型),Template(模板),View(视图)

Model:负责业务对象与数据库的对象(ORM):ORM对应对象--关系--映射

Template:负责如何把页面展示给用户;也就是一个HTML页面

View:负责业务逻辑,并在适当的时候调用model和Template

注意:Django还有一个url分发器,它的作用是将一个个URL的页面请求,分发给不同的view处理,view再调用相应的model和Template。

这就是一个Django的过程,用户输入网址,发送给服务器,Django里面的URL控制器就解析这个url然后确定相应要访问的页面,然后交给不同的视图处理,视图就去model中拿数据,model就去数据库中拿数据,model就把数据返回给视图,视图又把数据返回给模板,模板就把数据渲染,渲染之后就形成了一个HTML完整的页面,视图就将这个页面返回给浏览器。

安装

pip install django

验证安装是否成功:进入python命令行:import django;;django.get_version();即可看到版本号

  • 创建项目:

在你电脑里面创建一个合适的文件夹——>在cmd中cd进入那个文件夹——>使用<django-admin startproject name>(name是你的项目名字)

查看项目文件层级:<tree . /F>

  • 目录层级说明:

manage.py: 一个命令行工具,可以使我们用多种方式对Django项目进行交互

project目录下:_init_.py:一个空文件,它告诉python这个目录应该被看做一个python包

settings.py:项目的配置文件

urls.py:项目的URL生命

wsgi.py:项目与WSGI兼容的web服务器入口

基本操作

  • 设计表结构

配置数据库:注意:Django默认使用SQLite数据库,要在settings.py中,通过DATABASES选项进行数据库配置。

  • 配置mysql

#在_init_.py文件中加入这两行
import pymysql
pymysql.install_as_MySQLdb()

在settings.py中修改DATABASES选项:ENGINE变为:

'ENGINE': 'django.db.backends.mysql',

大部分数据库格式都是这样

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': "exampel",#数据库名
        'USER': "root", #用户名
        'PASSWORD': "123456", #数据库密码
        'HOST': "localhost", #数据库服务器IP
        'PORT': "3306", #端口
    }
}

完整如上。

  • 创建应用:

在一个项目中可以创建多个应用,每个应用进行一种业务处理

在cmd中进入刚刚创建的项目目录中执行

python manage.py startapp myapp1
#myapp1是你的应用名

目录说明:然后可以发现在项目文件夹下多了个myapp1文件夹,里面的admin.py表示站点,modles.py是为了写模型的,这个view.py是用来写视图的

  • 激活应用:

在settings.py中里面配置INSTALLED_APPS。

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'myapp1',#加入这个即可,上面都是他自带的
]
  • 定义模型:

概述:有一个数据表,就对应一个模型,在myapp1中的models.py中定义模型

模型类要继承models.Model类,模型类中的属性就对应我们数据库表中的字段

from django.db import models

# Create your models here.
#这是班级表
class Grades(models.Model):
    gname = models.CharField(max_length=20)
    gdate = models.DateTimeField()
    ggirlnum = models.IntegerField()
    gboynum = models.IntegerField()
    isDelete = models.BooleanField(default=False)
#这是学生表
class Students(models.Model):
    sname = models.CharField(max_length=20)#字段属于这个属性时必须定义max_length!
    sgender = models.BooleanField(default=True)
    sage = models.IntegerField()
    scontend = models.CharField(max_length=20)
    isDelete = models.BooleanField(default=False)
    #所属班级的话,由于是一对多的关系,外键写在多的里面,即写在学生这里
    sgrade = models.ForeignKey("Grades",on_delete=models.CASCADE)
    #关联外键,关联Grades中的主键,且注意写外键的时候要加上on_delete=models.CASCADE这个关键词

说明:不需要定义主键,在生成时自动添加,并且值自动添加

  • 在数据库中生成数据表:

生成迁移文件——>执行迁移

生成迁移文件:在项目所在文件夹的下面执行:

python manage.py makemigrations

成功的样子,其作用是在migrations下生成一个迁移文件,此时数据库中还没有表

Migrations for 'myapp1':
  myapp1\migrations\0001_initial.py
    - Create model Grades
    - Create model Students
#有错误的根据提示改错

继续执行:

python manage.py migrate
#执行迁移,相当于执行sql语句创建数据表

说明:以后我们去操作数据就要通过模型的对象,因为模型的对象对应表里面的一个字段,我们创造一个对象就是表里面的一条数据了。

  • 测试数据操作:

进入到python shell:python manage.py shell

引入一些包:

from myapp1.models import Grades,Students
from django.utils import timezone
from datetime import *

查询所有数据:

Grades.objects.all()
#类名.objects.all()
  • 添加数据:本质:创建一个模型类的对象实例
grade1 = Grades()
grade1.gname = "python04"
grade1.gdate = datetime(year=2019,month=3,day=15)
grade1.ggirlnum = 22
grade1.gboynum = 13
grade1.save()#这个对象调用save他就会存到数据库中
  • 再看数据:Grades.objects.all()
会输出: 
<QuerySet [<Grades: Grades object (1)>]>
#这样就很烦,所以回到models在Grades类中加入
    def __str__(self):
        return "%s-%d-%d" %(self.gname, self.ggirlnum, self.gboynum)
#这样就是设置了调用该类的时候就会执行这个
 Grades.objects.all()
#输出如下
<QuerySet [<Grades: python04-22-13>]>
  • 根据主键查看单个数据:
Grades.objects.get(id=2)
#类名.objects.get(id=2), id也就是主键,输出如下
<Grades: python03-21-12>
  • 在模型中修改数据
g = Grades.objects.get(id=2)
grade2.ggirlnum = 20
#模型对象.属性 = 新值
grade2.save()#记得save才会同步到数据库中。
  • 删除数据:
grade2.delete()
#模型对象.delete(),注意这是物理删除,数据库中的表里的数据直接被删除,不需要save同步
  • 关联对象:
grade1 = Grades.objects.get(pk=1)
stu = Students()
stu.name = "张胜三"
stu.sgender = False
stu.sage = 20
stu.scontend = "我叫张胜三"
stu.sgrade = grade1
stu.save()

获得关联对象的集合:需求:获取python04班级的所有学生

grade1.students_set.all()
#students_set是自带的,一对多,多的列名都是小写的
#格式:类名.关联的类名小写_set.all()

需求:创建张即,属于python04班级

stu3 = grade1.students_set.create(sname=u'张即',sgender=True,scontend='我叫张即',sage=45)
#注意这里的汉字需要用u进行转码,且这里的create直接存入到了数据库,不用save

注意汉字转码!直接添加到数据库中!

  • 启动服务器:

#格式
python manage.py runserver ip:port

注意:这个ip可以不写,不写的话代表本机ip。端口号默认8000,可以修改。也就是可以直接python manage.py runserver

这是一个纯python写的轻量级web服务器,仅仅在开发测试中使用!

  • Admin站点管理:

概述:主要负责内容发布和公告访问

内容发布:负责添加、修改、删除内容

  • 配置Admin应用:

在settings.py中的

INSTALLED_APPS添加'django.contrib.admin',默认是已添加的
  • 创建管理员用户:
python manage.py createsuperuser

依次输入用户名、邮箱、密码

汉化:修改settings.py中的LANGUAGE_CODE和TIME_ZONE

LANGUAGE_CODE = 'zh-Hans'

TIME_ZONE = 'Asia/Shanghai'
#保存刷新网页即可生效,延迟会有10s左右
  • 管理数据表:
  • 修改admin.py文件:
from .models import Grades,Students
#注册
admin.site.register(Grades)
admin.site.register(Students)
  • 自定义管理页面:

把你需要改的那个类的类名加上admin就行了,然后继承默认界面:modeladmin

并且注册的时候用到就行了。

from .models import Grades,Students
#注册
class GradeAdmin(admin.ModelAdmin):
    #列表页属性
    #显示字段
    list_display = ['pk', 'gname', 'gdate', 'ggirlnum', 'gboynum', 'isDelete']
    #过滤字段
    list_filter = ['gname']
    #搜索字段
    search_fields = ['gname']
    #分页
    list_per_page = 5

    #添加、修改页属性
    #可以规定属性的先后顺序,注意这里不能加pk,因为这里的pk我们弄的是自动生成的,而不是自己指定的
    #fields = ['ggirlnum', 'gboynum', 'gname', 'gdate', 'isDelete']
    #fields和fieldsets不能同时使用,fieldsets是给属性分组
    fieldsets = [
        ("num", {"fields":['ggirlnum', 'hboynum']}),
        ("base", {"fields":['gname', 'gdate', 'isDelete']}),
    ]
admin.site.register(Grades, GradeAdmin)#自定义的页面,要放在注册的这里
admin.site.register(Students)
  • 关联对象:

需求:在创建一个班级时可以直接添加几个学生

根据一对多的关系,在创建班级的时候,能直接添加几个学生

class StudentsInfo(admin.TabularInline):#这里也可以继承StackedInline
    model = Students
    extra = 2
class GradeAdmin(admin.ModelAdmin):#上面加的类名随意,只要在下面的inlines里面加入即可
    inlines = [StudentsInfo]
  • 将布尔值另外表示
    def gender(self):
        if self.sgender:
            return "男"
        else:
            return "女"
    #设置页面列的名称
    gender.short_description = "性别"
list_display = ['pk', 'sname', 'sage', gender, 'scontend', 'sgrade', 'isDelete']
  • 执行动作位置问题:
actions_on_bottom = True
actions_on_top = False

使用装饰器完成注册:

#admin.site.register(Students, StudentsAdmin)
#注释掉那个,在下面的类的头上加一个@admin.register(Students)
@admin.register(Students)
class StudentsAdmin(admin.ModelAdmin):
    def gender(self):

视图的基本使用

概述:在Django中,视图对web请求进行回应,视图就是一个python函数,在views.py文件(在你的应用的文件夹下)中定义

有多少视图呢,一般来说有几个页面就有几个视图

  • 定义视图:

也就是定义函数。在应用名目录下的views.py添加一下

from django.http import HttpResponse
#这里的request就是请求集,也就是浏览器给服务器的东西
def index(request):
    return HttpResponse("Weclome to my chamber")
#返回给浏览器什么东西,我们现在没学模板就返回一串文本

我们在输入网址后,网址要给url控制器,给其匹配,我们则在需要配置视图,然后配置url。

所以流程即:定义视图——配置url

配置url:修改你的项目名目录下的urls.py文件——在myapp1(你的应用目录下)创建一个urls.py文件

在项目名中的urls.py中加入

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', include('myapp1.urls')),
]

在新建的urls.py中加入

from django.conf.urls import url
from . import views
urlpatterns = [
    url(r'^$', views.index)#r防止字符被转义,^表示内容,$表示结束符
]

整个流程解释:我们的视图定义,需要配置,我们可以直接配置在应用目录下的urls.py中,但是为了隔离性,我们就在应用目录下创建一个urls.py,在这个里面调用那个视图,然后在外面的urls.py中包括上面的视图。我们以后在修改url的时候就直接在里面修改就行了,外面不需要再改了。

模板的基本使用:

概述:模板是HTML页面,可以根据视图中传递过来的数据进行填充

  • 创建模板目录(Directory):

在你的项目的根目录下创建:yaobinbin/templates/myapp1(注意这里的templates是和manage.py同级的)

  • 配置模板路径:

修改settings.py中的TEMPLATES

'DIRS': [os.path.join(BASE_DIR, 'templates')],

需求:当你键入网址/grades的时候显示所有的班级,

  • 1.在myapp1下创建模板。:在刚刚的myapp1创建两个html文件,grades.html和students.html

模板语法:1){{输出值,可以是变量,对象.属性}} 2){%执行代码段%}

下图是grades.html的代码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>班级信息</title>
</head>
<body>
    <h1>班级信息列表</h1>
    <u1>
{#        [python04,python05,python06]对象,这里会创建一个循环,每次循环创建一个li#}

        {% for grade in grades %}
        <li>
{#        这个grade.gname可以是python的变量,也可以是对象.属性,条件判断得用大括号百分号这种,加了个"#"就是表示后面变量在网页里面是可以点的,并且网页会跳转到你指定的地方#}
            <a href="#">{{grade.gname}}</a>
        </li>
        {% endfor %}
    </u1>
</body>
</html>
  • 2.定义视图
from .models import Grades,Students
def grades(request):
    #去模板里面取数据
    gradesList =Grades.objects.all()
    #将数据传递给模板,模板再渲染页面,将渲染好的页面返回给浏览器
    return render(request, 'myapp1/grades.html', {"grades": gradesList})
    #上面的大括号里面的grades就是给html的变量
  • 3.配置url
    url(r'^grades/$', views.grades),

需求:点击班级,显示对应班级的所有学生

1.修改grades.html

        <li>
{#        这个grade.gname可以是python的变量,也可以是对象.属性,条件判断得用大括号百分号这种,加了个"#"输入之后网页地址会变#}
            <a href="{{ grade.id }}">{{grade.gname}}</a>
        </li>

2.定义视图

def gradeStudents(request, num):
    #获得对应的班级对象
    grade = Grades.objects.get(pk=num)
    #获得班级下所有的学生列表
    studentList = grade.students_set.all()
    return render(request, 'myapp1/students.html', {"students": studentList})

3.配置url

url(r'^grades/(\d+)$',views.gradeStudents)
#这个(\d+)是数字

注意:当你增加一张表的时候,直接重新迁移文件,执行迁移即可。但是如果你要修改字段,最好直接删表,重新迁移

模型:

Django对各种数据库提供了很好的支持,Django为这些数据库提供了统一调用api,可以根据不同的业务需求选择不同的数据库

配置数据库:工程目录下的__init__.py文件加入两行代码——>在setting.py文件中修改——>定义模型类——>执行迁移生成数据表——>使用模型进行增删改查(crud)操作。

ORM:对象、关系、映射。它的作用就是把我们的CRUD操作转换成对应数据库的操作

  • 任务:

根据对象的类型生成表结构;按对象、列表的操作转换为sql语句;将sql语句查询到的结构转换为对象、列表

  • 优点:

极大的减轻了开发人员的工作量,不需要面对因数据库的变更而修改代码

  • 定义模型:
  • 模型、属性、表、字段间的关系

一个模型类在数据库中对应一张表,在模型类中定义的属性,对应该模型对照表的一个字段

属性命名限制:遵循标识符规则;由于Django的查询方式,不允许使用连续的下划线

逻辑删除:对于重要数据都做逻辑删除,不做物理删除,实现方法是定义isDelete属性,类型为BooleanField,默认值为FALSE

字段类型:
    AutoField
        一个根据实际ID自动增长的IntegerField,通常不指定。如果不指定,一个主键字段将自动添加到模型中
    CharField(max_length=字符长度)
        字符串,默认的表单样式是TextInput
    TextField
        大文本字段,一般超过4000使用,默认的表单控件是Textarea
    IntegerField
        整数
    DecimalField(max_dights=None, decimal_places=None)
        使用python的Decimal表示的十进制浮点数
        参数说明:DecimalField.max_dights 位数总数
                 DecimalField.decimal_places 小数点后的数字位数
    比如3.1415926的max_dights是8位,decimal_places是7位
    FloatField
        用python的float实例来表示的浮点数
    BooleanField
        True/False 字段,此字段的默认表单控制是CheckBoxInput
    NullBooleanField
        支持Null、True、False三种值
    DataField[auto_now=False,auto_now_add=False])
        使用Python的datatime.data实例表示的日期
        参数说明:
            DataField.auto_now:每次保存对象时,自动设置该字段为当前时间,用于最后一次修改的时间戳,它总是使用当前日期,默认为false
            DataField.auto_now_add当对象第一次被创建时自动设置当前时间,用于创建的时间戳,它总是使用当前日期,默认为false
        说明:auto_now,auto_now_add,and default 这些设置是相互排斥的,他们之间的任何组合将会发生错误的结果
    TimeField
        使用python的datatime》time实例表示的时间,参数同DataField
    DataTimeField
        使用python的datetime.datetime实例表示的日期和时间,参数同DateField
    FileField
        一个上传文件的字段
    ImageField
        继承了FileField的所有属性和方法,但对上传的对象进行校验,确保它是个有效的image

字段选项:通过字段选项,可以实现对字段的约束,在字段对象时通过关键字参数指定

null,blanke(如果未True,则该字段允许为空白,默认值为False),注意null是数据库范畴的概念,blank是表单验证范畴的。db_column字段的名称,如果未指定,则使用属性的名称,db_index若值为True,则在表中会为此字段创建索引,default默认值。primary_key主键设置。unique如果未TRUE,这个字段在表中必须有唯一值

关系:

  • 分类:

ForeignKey:一对多,将字段定义在多的端中

ManyToManyField:多对多,将字段定义在两段中,再来一张表。

OneToOneField:一对一,将字段定义在任意一端中

  • 用一访问多

格式:对象.模型类小写_set

示例:grade.students_set

  • 用一访问一

格式:对象.模型类小写

示例:grade.students

  • 访问id

格式:对象.属性_id

示例:student.sgrade_id

  • 创建模型类:

元选项:

在模型类中定义Meta类,用于设置元信息

db_table:定义数据表名,推荐使用小写字母,如果我们不写,数据表名默认项目名小写_类名小写

ordering:对象的默认排序字段,获取对象的列表时使用

    class Meta:
        db_table = "grades"
ordering=['id']#这是以id为升序取出
ordering=['-id']#这是以id为降序取出
注意:排序会增加数据库的开销

模型成员:

类属性、创建对象

类属性:隐藏的类属性:objects是manage类的一个对象,作用是与数据库进行交互。当定义模型类里没有指定管理器,Django为模型创建一个名为objects的管理器。

  • 自定义管理器:
#自定义模型管理器
    stuObj = models.Manager()

此时objects管理器就不存在了

  • 自定义管理器Manager类:

模型管理器是Django的模型进行与数据库进行交互的接口,一个模型可以有多个模型管理器

  • 作用:

向管理器类中添加额外的方法;修改管理器返回的原始查询集。:重写get_queryset()方法

#注意这个Manager是大写的m
class StudentsManger(models.Manager):
    def get_queryset(self):
        return super(StudentsManger,self).get_queryset()\
            .filter(isDelete=False)
#这个filter是将符合条件的过滤进来
#这是学生表
class Students(models.Model):
    #自定义模型管理器
    stuObj = models.Manager()
    stuObj2 = StudentsManger()

这里是自定义模型管理器,可以不显示isDelete=True的用户

def students(request):
    studentsList = Students.stuObj2.all()
    return render(request, 'myapp/students.html', {"students": studentsList})
#urls.py文件
url('^students/$', views.students),
#通过调用stuObj2管理器就能将isDelete为真的过滤掉
  • 创建对象:

目的:想数据库中添加数据;

当创建对象时,django不会对数据库进行读写操作,当调用save()方式时才与数据库交互,将对象保存到数据库表中

注意:__init__方法已经在父类models.Model中使用。在自定义的模型中无法使用。

方法:在模型类中增加一个类方法或者在自定义管理器中添加一个方法

方法一:在模型类中增加一个类方法

#这个是在models.py文件中 
#定义一个类方法创建对象
    @classmethod
    def createStudent(cls, name, age, gender, content,
                      grade, lastTime, createTime, isD=False):#这个cls就代表了Students这个类
        stu = cls(sname=name, sage=age, sgender=gender, scontend=content,sgrade=grade,
                  last_time=lastTime, create_time=createTime, isDelete=isD)
        return stu
#这个是在views.py中
def addstu(request):
    grade = Grades.objects.get(pk=1)
    stu = Students.createStudent("大黄", 34, True, "my name is huang", grade,
                                 "2017-8-10", "2017-5-6")
    stu.save()
    return HttpResponse("成功")
#这个是在urls.py中
url(r'^addstu/$', views.addstu),

方法二:在自定义管理器中添加一个方法

#models.py中
    def createStu(self, name, age, gender, content,
                      grade, lastTime, createTime, isD=False):
        stu = self.model()
        #print(type(grade))
        stu.sname = name
        stu.sage = age
        stu.sgender = gender
        stu.scontend = content
        stu.sgrade = grade
        stu.last_time = lastTime
        stu.create_time = createTime
        return stu
#views.py中
def addstu2(request):
    grade = Grades.objects.get(pk=1)
    stu = Students.stuObj2.createStu("小黄", 24, True, "my name is huang", grade,
                                 "2018-8-10", "2017-5-6")
    stu.save()
    return HttpResponse("成功")
#urls.py中
url(r'^addstu2/$', views.addstu2),

模型查询:

查询集:表示从数据库获取的对象集合

查询集可以有多个过滤器(我的查询集是有这个对象的所有数据,而我要的不是所有的数据而是固定的数据)

过滤器就是一个函数,基于所给的参数限制查询集结构

从sql角度来说,查询集和select语句等价,过滤器就像where条件

在管理器上调用过滤器方法返回查询集;查询集经过过滤器筛选后返回新的查询集,所以可以写成链式调用;惰性执行:创建查询集不会带来任何数据的访问,直到调用数据时,才会访问数据;

直接访问数据的情况:迭代、序列化、与if合用;

  • 返回查询集的方法称为过滤器:

all()、

filter():filter(键=值,键=值)或者filter(键=值).filter(键=值);这个是且的关系;保留符合条件的数据

exclude():过滤掉符合条件的数据

order_by():排序

values():一条数据就是一个对象(字典),返回一个列表

  • 返回单个数据:

get():返回一个满足条件的对象;注意:如果没有找到符合条件的对象,模型类会引发一个异常模型类.DoesNoteExists异常。如果找到多个对象,也会引发异常:模型类".MutipleObjectsReturned"异常

count():返回当前查询集中的对象个数;first():返回查询集中的第一个对象;last():返回查询集中的最后一个对象;

exists():判断查询集中是否有数据,如果有数据返回True

  • 限制查询集数量:

查询集返回列表:可以使用下标的方法进行限制,等同于sql中的limit语句。注意下标不能是负数

#views.py
def students3(request):
    studentsList = Students.stuObj2.all()[0:3]
    return render(request, 'myapp/students.html',
                  {"students": studentsList})
#urls.py
    url('^students3/$', views.students3),

需求:根据你输入地址的数量显示数量

#views.py
#分页查询,每一页显示固定个数
def stupage(request, page):
    #0-3 3-6 6-9
    #1   2   3
    page = int(page)
    studentsList = Students.stuObj2.all()[(page-1)*3:page*3]
    return render(request, 'myapp/students.html',
                  {"students": studentsList})
#urls.py
url('^students/(\d+)/$', views.stupage),
  • 查询集的缓存:

概述:每个查询集都包含一个缓存,来最小化的对数据库访问;在新建的查询集中,缓存首次为空,第一次对查询集求值(取数据时),会发生数据缓存,Django会将查询出来的数据做一个缓存,并返回查询结构,以后的查询直接使用查询集的缓存

  • 字段查询:

概述,比较运算符,聚合函数,F对象,Q对象

实现了sql中的where查询,作为方法filter(),exlcude(), get()的参数;

语法:属性名称__运算符 = 值 (两个下划线)

外键:属性名.id; 转义:sql的like是使用%作为占位符。如何匹配数据中的%,就要使用转义

转义使用:filter(sname__contains=%),就可以直接匹配不用转义

比较运算符:exact:判断,大小写敏感;contains:是否包含

studentsList = Students.stuObj2.filter(sname__contains="黄")

startswith和endswith:以value开头或结尾,大小写敏感

studentsList = Students.stuObj2.filter(sname__startswith="大")

以上四个在前面加上一个i就表示不区分大小写,iexact、icontains、istartswith、iendswith

isnull和isnotnull;in是否包含在范围内

studentsList = Students.stuObj2.filter(pk__in=[1, 3, 5])

gt、gte、lt、lte:分别对应大于、大于等于、小于、小于等于

studentsList = Students.stuObj2.filter(sage__gt=22)

year、month、day、week_day、hour、minute、second:日期

studentsList = Students.stuObj2.filter(last_time__year=2019)
  • 跨关联查询:

语法:模型类名__属性名__比较运算符

#描述带有‘大黄’的名字的学生是哪个班级的
    grade = Grades.objects.filter(
        students__scontend__contains='大黄'
    )
  • 查询快捷:

pk:主键

  • 聚合函数:

使用aggregate()函数返回聚合函数的值

Avg、Count、Max、Min、Sum

from django.db.models import Max,Min
maxAge = Students.stuObj2.aggregate(Max('sage'))
print(maxAge)
  • F对象:

可以使用一个模型的A属性与B属性进行比较(一个表中的两个属性进行比较)

from django.db.models import F,Q
def grades(request):
    g = Grades.objects.filter(ggirlnum__lt=F('gboynum'))
    print(g)
    return HttpResponse("0000000")

支持F对象的数据运算

g = Grades.objects.filter(ggirlnum__lt=F('gboynum')+20)
  • Q对象:

概述:过滤器的方法中的关键词参数。条件为And模式

需求:进行or查询。使用Q对象。即求并集

from django.db.models import F,Q
studentsList = Students.stuObj2.filter(Q(pk__lte=6) | Q(sage__gt=50))
    return render(request, 'myapp/students.html',
                  {"students": studentsList})
#如果单纯是下面这种情况就是单纯的匹配了
studentsList = Students.stuObj2.filter(Q(pk__lte=6))
#studentsList = Students.stuObj2.filter(~Q(pk__lte=6))这种就是把上面那种取反

视图:

Django在urls.py里面设置namespace的时候注意:https://blog.csdn.net/weixin_40841752/article/details/79335345

  • 404视图设置:
#settings设置
DEBUG = False
ALLOWED_HOSTS = ['*']
#另外注意要在templates目录下直接新建404.html文件。还注意templates路径设置。这样设置即可
#还有关于request_path参数

GET配置:

  • get获取变量的两种方式:
#urls.py中设置
    url(r'^get1', views.get1),
    url(r'^get2', views.get2),
#views.py中设置
def get1(request):
    a = request.GET.get('a')
    b = request.GET.get['b']#这种方式也是可以的
    c = request.GET.get('c')
    return HttpResponse(a+" "+b+" "+c)
def get2(request):
    a = request.GET.getlist('a')
    a1 = a[0]
    a2 = a[1]
    c = request.GET.get('c')
    return HttpResponse(a1 + " " + a2 + " " + c)
  • 软链接应用:
#项目目录下的urls.py
urlpatterns = [
    path('admin/', admin.site.urls),
    path(r'huaq/', include(('myapp.urls', 'myapp'), namespace="myapp")),
]
#注意那个huaq不能用bin这样特殊关键词,要不然不会生成动态链接
#应用目录下的urls.py
url(r'showregist/$', views.showregist),
    url(r'regist/$', views.regist),
#regist.html
<form action="regist/" method="post">
        姓名: <input type="text" name="name" value=""/>
        <hr/>
        性别: <input type="radio" name="gender" value="1"/>男<input type="radio" name="gender" value="0"/>女
        <hr/>
        年龄: <input type="text" name="age" value=""/>
        <hr/>
        爱好: <input type="checkbox" name="hobby" value="power"/>权利
        <input type="checkbox" name="hobby" value="money"/>金钱
        <input type="checkbox" name="hobby" value="food"/>食物
        <hr/>
        <input type="submit" value="注册"/>
        </form>
#views.py中
def showregist(request):
    return render(request, 'myapp/regist.html')
def regist(request):
    return HttpResponse("啊哈哈哈哈成功")

#注意:html的修改要重新启动服务器才会生效

注意这里的hobby由于是checkbox,其传入的数据不止一个,所以要用getlist来接收

hobby = request.POST.getlist("hobby")

#注意表单提交的usrf的关闭(在settings.py中注销中间组件:

#'django.middleware.csrf.CsrfViewMiddleware',

  • ps: 关于后面的在urls.py调用views.py中的视图代码不作记录
  • HttpResponse属性查看:
#views.py
def showresponse(request):
    res = HttpResponse()
    res.content = "U are good"
    print(res.content)
    print(res.status_code)
    print(res.charset)
    return res
#输出
b'U are good'
200
utf-8

cookie使用

def cookietext(request):
    res = HttpResponse()
    cookie = request.COOKIES
    #res.write("<h1>"+cookie["binbin"]+"</h1>")
    cookie = res.set_cookie("binbin", "good")
    return res
#第一次写入cookie:key为"binbin",值为"good"
def cookietext(request):
    res = HttpResponse()
    cookie = request.COOKIES
    res.write("<h1>"+cookie["binbin"]+"</h1>")
    #cookie = res.set_cookie("binbin", "good")
    return res
#第二次取出cookie并使用

第二次页面输出:记住:以后我们再去发生请求,都会带着这个cookie。对于我这个服务器只能使用"binbin"。

说明:假如你注册好了, 你登陆了,我就给你返回一个cookie,那么这个cookie我就能给你存一个token值(一个键对应一个token值),那么以后你再发生请求了,服务器接收你的请求,先拿出cookie,找到对应的token值,先验证token值,验证成功就能登陆了。删除cookie删除对应的键就行了

重定向:

你输入一个网址之后,让其自动转到另外一个view那里去。

#重定向
from django.http import HttpResponseRedirect
from django.shortcuts import redirect
def redirect1(request):
    return HttpResponseRedirect('/huaq/redirect2')
    #return redirect('/huaq/redirect2')
def redirect2(request):
    return HttpResponse("我是重定向之后的视图哦")
#第二个redirect(to)是简写

session实现登陆用户返回登陆页面信息记录

#views.py
from django.http import HttpResponseRedirect
from django.shortcuts import redirect
def redirect1(request):
    return HttpResponseRedirect('/huaq/redirect2')
    #return redirect('/huaq/redirect2')
def redirect2(request):
    return HttpResponse("我是重定向之后的视图哦")
def main1(request):
    #取session,要用session.get而不是POST.get
    username = request.session.get('name', "游客")
    print(username)
    return render(request, 'myapp/main.html', {'username': username})
def login(request):
    return render(request, 'myapp/login.html')
def showmain(request):
    print("****")
    #这个username是从html里面POST过来的变量名即:name值
    username = request.POST.get('username')
    #存储session
    request.session['name'] = username
    # 注意这个路径
    return redirect('/huaq/main1/')
#main.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>我的</title>
</head>
<body>
    <h1>欢迎:{{ username }}</h1>
    <a href="/huaq/login/">登陆</a>
</body>
</html>
#login.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <form action="/huaq/showmain/" method="post">
        <input type="text" name="username"/>
        <input type="submit" value="登陆"/>
    </form>
</body>
</html>
#urls.py
    url(r'^main1/$', views.main1),
    url(r'^login/$', views.login),
    url(r'^showmain/$', views.showmain),

#注意这个“^”号一定要加,要不然遇到main的时候,会直接匹配到main1(我最开始是main,会有变化,main1没影响)而不是showmain。!

模板:

  • 过滤器:

url:反向解析

主项目目录下的url的namespace和url对应的名字结合,放到模板中,他就会自动生成对应的链接在你指定的链接后面,动态。

#主项目url
path('', include('myapp.urls', namespace="myapp")),
#应用内url
url(r'^good/(\d+)/$', views.good, name="good"),
#index.html
<a href="/good/">链接</a>
    <a href="{% url 'myapp:good' 1 %}">链接</a>

这里使用了url反向解析,就会根据命名空间+name组合生成。并且后面的参数和前面记得要有一个空格

点击链接后跳转页面:http://127.0.0.1:8000/good/1/

分享到 :
0 人收藏
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

积分:7942463
帖子:1588486
精华:0
期权论坛 期权论坛
发布
内容

下载期权论坛手机APP