今日的内容:

a. 路由系统

1. 创建app

2. 路由的分组

3. 路由的分发

-正则表达式匹配

b. django的orm(模型model)

1. 创建模型的步骤

2. orm基本的增删改查

3. 正向查询和反向查询

注意事项:

1. 前台传给后台一个列表时,后端如何接受:

request.POST.getlist(字段名)

2. 前台传给后台一个列表时,需要在ajax请求中增加一个参数:

traditional: true

3. 多选框设置选中状态时,可以使用

$("select的选择器").val(列表)

4. cookie的参数设置

obj = render(request,'a.html')

obj.set_cookie(key,values,max_age,expires,path,

domain,secure,httponly)

参数详解

"""

key, 键

value=, 值

max_age=None, 超时时间

expires=None, 指定过期时间IE 专用 date = datetime.datetime() expires=date

path='/', cookie有效路径

domain=None, Cookie生效的域名

secure=False, https传输

httponly=False 只能http协议传输,无法被JavaScript获取(不是绝对,底层抓包可以获取到也可以被覆盖)

"""

5. 删除Cookie

def logout(request):

rep = redirect("/login/")

rep.delete_cookie("user") # 删除用户浏览器上之前设置的usercookie值

return rep

6. 获取Cookie

username = request.COOKIES.get('username') # 取出登录用户名

7. cookie的加盐

#通过加盐的方式为cookie签名。

obj.set_signed_cookie('kkk','vvv', salt='123456')

#获取经过签名后的cookie值。

request.get_signed_cookie('kkk',salt='123456')

# 目录结构

migrations# 模型操作的迁移文件

init

admin# 管理文件,django admin的时候会用到

apps# 应用信息定义文件,在其中生成了类AppCongfig,该类用于定义应用名等Meta数据

models# 添加模块层数据类的文件,orm框架时使用

tests# 测试代码文件

views# 视图文件

路由分组

对多个视图进行一个分组,比如class为一个组,所有跟class相关的增,删,改,查视图都放在这个app中。各司其职,互不干扰。相比之前把所有的代码写到urls中,功能分划更清晰。

创建app的两种方式:

1. 使用pycharm创建django项目时,可以创建。缺点:只能创建一个

2. 命令行创建python3 manage.py startapp app名称(可创建多个),

django使用的什么版本的解释器,就需要用对应的解释器创建app

需要在对应的目录下创建

分组:

第一种方式

a. 项目下的urls.py中

from *** import views

urlpatterns = [

url(r'^test/', views.test),

]

# 缺点,只能导入一个app,多个app会导致名称空间被污染

第二种方式

django项目下的urls.py文件,注意:需要导入include模块

from django.conf.urls import url,include

urlpatterns = [

url(r'^classes/',inclued("classes.urls")),

url(r'^student/',inclued("student.urls")),

url(r'^teacher/',inclued("teacher.urls"))

]

在对应的app下,创建一个urls.py文件

对应app的urls.py

form django.conf.urls import url

from classes import views

urlpatterns = [

url(r'^get_classes/',views.get_classes),

]

对应app下的views.py文件内容为:

from django.shortcuts import render,HttpResponse

# Create your views here.

def get_classes(request):

return HttpResponse("get_classes")

第二种方式的总结:

客户端访问127.0.0.1:8000/classes/get_classes时,先进入到项目下的urls.py文件进行匹配

根据项目下urls.py中的对应关系,进入到各个app项目下的urls.py文件中进行匹配

根据各个app下的urls.py中的对应关系,匹配成功请求路径后,执行对应app项目下views.py文件下的函数。

路由分发

from app01 import views

urlpatterns = [

url(r'^test/(?P\w+)/(?P\w+)', views.test),

]

# app01项目下views.py文件:

def test(request,name,id):

print(name)

print(id)

return HttpResponse("test")

# 浏览器访问

http://127.0.0.1:8000/test/0123/plf

# -------------------------views.py中打印结果---------------------

plf

0123

当浏览器中输入一个不存在的地址时,我们可以在浏览器中匹配对应的路径,然后为不存在的url,专门设置一个页面

from app01 import views

urlpatterns = [

url(r'^', views.notfound),

]

反向路由

当一个路径很长的时候,我们可以在路由系统中,设置一个变量a,用来代替这个路径,之后我们在form表单中action中写入{% url "a" %}即可.

# 路由系统中的写法

urlpatterns = [

url(r'^logindbsjhalbdhaskbhdkjsabhdkbashkdbhsabdhsja/$', views.login, name='test'),

]

# 对应的html的页面中写法:

django中请求处理方式有2种:FBV 和 CBV

第一种:FBV(function base views)

就是在视图里使用函数处理请求

urls.py

from django.conf.urls import url, include

# from django.contrib import admin

from mytest import views

urlpatterns = [

# url(r'^admin/', admin.site.urls),

url(r'^index/', views.index),

views.py

from django.shortcuts import render

def index(req):

if req.method == 'POST':

print('method is :' + req.method)

elif req.method == 'GET':

print('method is :' + req.method)

return render(req, 'index.html')

第二种:CBV(class base views)

就是在视图里使用类处理请求。

urls.py

from mytest import views

urlpatterns = [

# url(r‘^index/‘, views.index),

url(r‘^index/‘, views.Index.as_view()),

]

# 注:url(r‘^index/‘, views.Index.as_view()), 是固定用法。

views.py

from django.views import View

class Index(View):

def get(self, req):

print('method is :' + req.method)

return render(req, 'index.html')

def post(self, req):

print('method is :' + req.method)

return render(req, 'index.html')

# 注:类要继承 View ,类中函数名必须小写。

'''

'get', 'post', 'put', 'patch', 'delete', 'head', 'options', 'trace'

form 只支持 post和 get

ajax 支持 所有的方法

'''

ORM框架

1. 先配置mysql的连接地址

# 在settings.py文件中,写入自己需要连接的数据库

DATABASES = {

# 'default': {

# 'ENGINE': 'django.db.backends.sqlite3',

# 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),

# }

'default': {

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

'NAME':'orm',

'USER': 'root',

'PASSWORD': '123456',

'HOST': '192.168.81.161',

'PORT': '3306',

}

}

2. 在app中的__init__.py文件中导入pymysql模块

import pymysql

pymysql.install_as_MySQLdb()

3. 在app项目下models.py文件中创建表.一个类一个表

# 类需要继承models.Model

from django.db import models

# Create your models here.

class UserInfo(models.Model):

id = models.AutoField(primary_key=True)

name = models.CharField(max_length=32)

age = models.CharField(max_length=32)

ut = models.ForeignKey("UserType",null=True)

4. 修改配置文件

​把我们的应用添加到对应的settings.py的INSTALLED_APPS 中:

INSTALLED_APPS = [

'django.contrib.admin',

'django.contrib.auth',

'django.contrib.contenttypes',

'django.contrib.sessions',

'django.contrib.messages',

'django.contrib.staticfiles',

'****', #我们创建的应用

]

4. 创建表

python manage.py makemigrations ## 生成迁移文件

python manage.py migrate ## 生成实际的表

ps: 如果修改了models.py中的代码,需要重新执行上面的两行代码

5. 基本操作

第一种方式

models.users.objects.create(username='xsmile',password=12345)

第二种方式

a = {'username':"plf",'passsword':'123456'}

models.users.objects.create(**a)

第三种方式:插入多条数据

info = [

models.UserInfo(name="root1",age=34,ut_id=1),

models.UserInfo(name="root2",age=34,ut_id=2),

models.UserInfo(name="root3",age=34,ut_id=3),

models.UserInfo(name="root4",age=34,ut_id=4),

models.UserInfo(name="root5",age=34,ut_id=5),

models.UserInfo(name="root6",age=34,ut_id=6),

models.UserInfo(name="root7",age=34,ut_id=7),

]

models.UserInfo.objects.bulk_create(info)

删除

Test.objects.filter(name__contains='jack').delete()

Test.objects.filter(name__contains='apollo1').update(name='Jack')

单表查询

models.Tb1.objects.filter(id__lt=10, id__gt=1) # 获取id大于1 且 小于10的值

models.Tb1.objects.filter(id__in=[11, 22, 33]) # 获取id等于11、22、33的数据

models.Tb1.objects.exclude(id__in=[11, 22, 33]) # not in

models.Tb1.objects.filter(name__contains="ven") # 获取name字段包含"ven"的

models.Tb1.objects.filter(name__icontains="ven") # icontains大小写不敏感

models.Tb1.objects.filter(id__range=[1, 3]) # id范围是1到3的,等价于SQL的bettwen and

类似的还有:startswith,istartswith, endswith, iendswith

date字段还可以:

models.Class.objects.filter(first_day__year=2017)

多表查询(外键查询)

1. 正向查询(通过关联的字段ut,直接使用点语法获取另外一张表的字段数据)

objs = models.UserInfo.objects.filter(ut_id__gt=2,ut__title="正常员工")

print(objs)

for i in objs:

print(f"id:{i.id} {i.name} {i.age} {i.ut.title}")

正向查询

第一种:按对象查找

语法

对象.关联字段.字段

book_obj = models.Book.objects.first() # 第一本书对象

print(book_obj.publisher) # 得到这本书关联的出版社对象

print(book_obj.publisher.name) # 得到出版社对象的名称

第二种:按照字段查找

语法

关联字段__字段

print(models.Book.objects.values_list("publisher__name"))

反向查询

第一种:按照对象查找

语法

对象.表名_set

publisher_obj = models.Publisher.objects.first() # 找到第一个出版社对象

books = publisher_obj.book_set.all() # 找到第一个出版社出版的所有书

titles = books.values_list("title") # 找到第一个出版社出版的所有书的书名

第二种:按照字段查找

语法

表名__字段

titles = models.Publisher.objects.values_list("book__title")

Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐