##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