##Django框架路由系统
1、伪静态
cnblogs:网站中的地址:
https://www.cnblogs.c om/linhaifeng/articles/7133167.html
自己项目中的访问地址:
http://127.0.0.1:8000/up_studnet/?id=12
如何实现?
路由分发
#2、路由分发
url:
url(r'^index/(\w+)/(\w+)/', index),
url(r'^test/(?P<id>\w+)/(?P<name>\w+)/', test),
对应函数:
def index(request, name, id):
print(id , name)
return HttpResponse('index')
def test(request, name, id):
print(id , name)
return HttpResponse('test')
出现问题:
1、index函数:在web端访问:
http://127.0.0.1:8000/index/18/icon
http://127.0.0.1:8000/index/icon/18
会导致后台接收的id和name参数会随之变化
解决方案:
1、test函数:使用正则,然后起别名方式可以解决该问题
#3、路由正则
url(r'^test2/$', test2)
思路:使用正则,当出现访问的地址不存在时,返回浏览器自定义的not fund错误
url(r'^', notfound) 需要写到最下面
#4、反向路由:
优点:
设置反向路由以后,只需要修改后台连接地址就可以,无需要动前端代码
后台url:
url(r'^logindjsajdbjsabdsabdbsabdhsabdhbsahbdsaasa/$', login, name='xxx')
xxx为自定义
前台:
<form action="{% url 'xxx' %}">
<input type="text">
</form>反向解析(带参数的) url(r'^indexxasdaskkdjlksajdlksaj/(\d+)/', index,name='index'), 有名无名均按照下面方式使用即可: 前端:{% url 'index' 1 %} 后端:reverse('index',args=(1,))
#5、django创建app
python3 manage.py startapp 自定义app名称
在settings.py配置文件中添加app02使其生效
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
‘app02’,
]
app02参数介绍:
admin.py : 写和django-admin相关的配置
apps: 对app的配置
models: 数据表模型 (********)
tests: 测试
views: 视图函数 (*******)
#6、路由分组
浏览器访问:127.0.0.1:8000/app02/teachers
总:项目中urls.py;
先导入include
from django.conf.urls import url,include
在路由分发中添加
url(r'^app02/', include('app02.urls')),
url(r'^app03/', include('app03.urls')),
分:app02中urls.py:
from app03 import views
urlpatterns = [
url(r'^students/', views.studnets)
]
建议 大家使用: 创建一个app, 然后在app的views.py中写自己的业务逻辑函数, urls.py 路由匹配, 只是进行分发
##Django框架视图函数
我们之前写过的都是基于函数的view,就叫FBV。还可以把view写成基于类的。
就拿我们之前写过的添加班级为例:
#1、FBV:函数视图
function based view # FBV版添加班级 def add_class(request): if request.method == "POST": class_name = request.POST.get("class_name") models.Classes.objects.create(name=class_name) return redirect("/class_list/") return render(request, "add_class.html")
#2、CBV:类视图
class based view
总:项目中urls
urlpatterns = [
url(r'^app03/',include('app03.urls')),
]
分:app03中urls
from app03 import views
urlpatterns = [
url(r'^login/',views.Login.as_view()),
]
分:app03中视图函数views
from django.views import View
class Login(View):
def get(self,request):
return render(request,'login.html')
def post(self,request):
uname = request.POST.get('username')
print(uname)
return HttpResponse('ok')
分:templates目录下login.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form action="/app03/login/" method="post">
<input type="text" name="username">
<input type="submit" value="tijiao">
</form>
</body>
</html>
浏览器:http://127.0.0.1:8000/app03/login/
get请求找类中get方法
post请求找类中post方法
注意:
使用CBV时,urls.py中也做对应的修改:
# urls.py中 url(r'^add_class/$', views.AddClass.as_view()),#3、给视图加装饰器 FBV本身就是一个函数,所以和给普通的函数加装饰器无差: 类中的方法与独立函数不完全相同,因此不能直接将函数装饰器应用于类中的方法 ,我们需要先将其转换为方法装饰器。 Django中提供了method_decorator装饰器用于将函数装饰器转换为方法装饰器。 如: # CBV版添加班级 from django.views import View from django.utils.decorators import method_decorator class AddClass(View): @method_decorator(wrapper) def get(self, request): return render(request, "add_class.html") def post(self, request): class_name = request.POST.get("class_name") models.Classes.objects.create(name=class_name) return redirect("/class_list/")
#4、参数介绍
'get': 请求数据
'post':提交数据
'delete': 删除数据
'put': 更新数据
'patch': 更新部分数据
ps:
form表单提交 只支持get、post
ajax支持多个
核心:
def dispatch(self, request, *args, **kwargs):
super(Login, self).dispatch(request, *args, **kwargs)
dispatch方法:自定制的预处理操作:如权限管理,对登录时可以做一些预处理操作
##Django框架ORM
#ORM配置
"""
1、创建数据库
2、配置mysql的数据库链接
setting文件里的DATABASES设置为
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 's8day61', ## 数据库名称
'USER': 'root',
'PASSWORD': '123', ## 安装 mysql 数据库时,输入的 root 用户的密码
'HOST': '127.0.0.1',
}
3、注册app
也是在settings文件中的INSTALLED_APPS
把你的app文件名加进去
4、需要把mysqldb设置为pymysql链接
python3中用的是pymysql
python2中使用的是mysqldb
为了兼容,都改成pymysql
app下的__init__文件
import pymysql
pymysql.install_as_MySQLdb()
5、创建表(2个命令)
python manage.py makemigrations ## 生成migrations文件
python manage.py migrate ### 根据生成的migrations文件生成表
"""
#案例:在app03中models.py建立模型表
from django.db import models
# Create your models here.
class Department(models.Model):
# 主键id 在django中会帮我们创建,所以可以省略id字段
title = models.CharField(max_length=32,null=True)
class Userinfo(models.Model):
id = models.AutoField(primary_key=True)
name = models.CharField(max_length=32,null=True)
age = models.CharField(max_length=32,null=True)
email = models.CharField(max_length=32,default="")
# 默认会创建外键字段,字段名ud_id 回家一个_id
ud = models.ForeignKey("Department",null=True)
#注意
模型表中的字段增删改查都需要刷新上述两个命令
python3 manage.py makemigrations
python3 manage.py migrate
#单表的增删改查
# 先导入models文件
from class_app import models
### 增加
# models.Department.objects.create(title="保安部")
# models.Department.objects.create(title="开发部")
### 查询
### 查询所有 ==> 列表里套对象
# res = models.Department.objects.all()
### <QuerySet [<Department: Department object>, <Department: Department object>]>
# for row in res:
# print(row.id, row.title)
### 指定字段查询 values ==> 列表里套字典
### select title from department ;
# res = models.Department.objects.values("title").all()
# ### <QuerySet [{'title': '保安部'}, {'title': '开发部'}, {'title': '开发部'}]>
# for row in res:
# print(row['title'])
### 指定字段查询 value_list==> 列表里套元组
# res = models.Department.objects.values_list("title").all()
# ### <QuerySet [('保安部',), ('开发部',), ('开发部',)]>
# print(res)
### select * from xxx where title = "开发部" 过滤
# res = models.Department.objects.filter(title='开发部').all()
#
# print(res)
# res = models.Department.objects.filter(id__lt = 3) ### less then 小于
# res = models.Department.objects.filter(id__gt = 3) ### greater then 大于
## 取第一条数据
# res = models.Department.objects.all().first()
# print(res)
# 删
models.Classes.objects.filter(name="xxx").delete()
# 改
models.Classes.objects.filter(name="xxx").update(name="ooo")
# 如果需要改的值很多,并且在一个字典里,也可以用**打散
models.Classes.objects.filter(name="xxx").update(**dic)
#一对多表
### 增加
# models.UserInfo.objects.create(uname = "icon", age=15, email="dddd@qq.com", ud_id=2)
# models.UserInfo.objects.create(uname = "创彬", age=16, email="gggg@qq.com", ud_id=2)
# models.UserInfo.objects.create(uname = "owen", age=18, email="hhhh@qq.com", ud_id=1)
# info = {"uname":'zekai2', 'age':13, "email":'123@qq.com', "ud_id":2}
# models.UserInfo.objects.create(**info)
### 查询
### 正向查询
# res = models.UserInfo.objects.all()
# for row in res:
# print(row.id, row.uname, row.age, row.ud.title)
### 反向查询
### 写法: 小写的表名_set.all()
# res = models.Department.objects.all()
# for row in res:
# print(row.title, row.userinfo_set.all())
### 神奇的双下画线
res = models.UserInfo.objects.values('id', 'uname', "ud__title").all()
print(res)
res = models.UserInfo.objects.values_list('id', 'uname', "ud__title").all()
print(res)
#django中orm的表的正查与反差
# 如果一张表和其他的表建有外键关系,那么从这张表查另一张表称为正查,反之称为反差
# 先建立两个外键关系的表
class Classes(models.Model): # 如果我们不设置一张表的id时,django会自动帮我创建一个自增的主键id
name = models.CharField(max_length=32,null=True)
class Students(models.Model):
name = models.CharField(max_length=32,null=True)
cid = models.ForeignKey("Classes",null=True) # 会自动帮我们和另一张表的主键建立外键关系
# 正查
for obj in students:
print(obj.cid.name) # 可以直接通过对象点里面的属性就可以点出另一个类的对象,可以继续取值
# 反查
obj.student_set.all() # 就是查出所有的对象
# 还可以通过下划线直接取到另一张表的值
# values是取出括号里对应的值,通过列表里套字典的形式
# values_list 是取出括号里对应的值, 通过列表里套元组的形式
models.Classes.objects.values("id","name","cid__name").all()
#双下划线
# 查询时通过外键名__另一张表的名字 可以查到关联表的值
# eg:
models.Classes.objects.values("id","name","cid__name").all() #这个cid__name可以查询到关联表对应的name
# 查询时可以在filter中加入限制条件 __lt 代表小于 __gt代表大于
# eg:
models.Classes.objects.filter(id__lt = 3).all() # id < 3
models.Classes.objects.filter(id__gte = 3).all() # id >= 3