zoukankan      html  css  js  c++  java
  • Django之路由层、有名无名分组、反向解析、Django版本区别、三板斧、路由分发

    表关系创建

    	一对多
    	多对多
    	一对一
    # 如何判断  换位思考 
    	以图书管理管理系统
    		图书表
    			图书和出版社是一对多的外键关系
    			一对多外键关系 外键字段建在多的那一方
    

    一对一关系建立:author_detail = models.OneToOneField(to='AuthorDetail')

    ForeignKey字段以及OneToOneField字段 在创建表的时候orm都会自动给该字段加_id的后缀
    无论自己有没有加
    
    class Author(models.Model):
    	name = models.CharField(max_length=32)
    	phone = models.BigIntegerField()
    	# 一对一外键关系建立
    	author_detail = models.OneToOneField(to='AuthorDetail')
    

    多对多关系建立:authors = models.ManyToManyField(to='Author')

    class Book(models.Model):
    	# id是自动创建的 我们就不写了
    	title = models.CharField(max_length=64)
    	# price为小数字段 总共8位小数位占2位
    	price = models.DecimalField(max_digits=8,decimal_places=2)
    
    	# 书籍与出版社 是一对多外键关系
    	publish = models.ForeignKey(to='Publish')  # 默认关联字段就是出版社表的主键字段
    	# publish = models.ForeignKey(to=Publish)  # to后面也可以直接写表的变量名 但是需要保证该变量名在当前位置的上方出现
    	# 书籍与作者   是多对多外键关系
    	authors = models.ManyToManyField(to='Author')  # 书籍和作者是多对多关系
    

    一对多关系建立:publish = models.ForeignKey(to='Publish')

    class Book(models.Model):
    	# id是自动创建的 我们就不写了
    	title = models.CharField(max_length=64)
    	# price为小数字段 总共8位小数位占2位
    	price = models.DecimalField(max_digits=8,decimal_places=2)
    
    	# 书籍与出版社 是一对多外键关系
    	publish = models.ForeignKey(to='Publish')  # 默认关联字段就是出版社表的主键字段
    	# publish = models.ForeignKey(to=Publish)  # to后面也可以直接写表的变量名 但是需要保证该变量名在当前位置的上方出现
    

    django请求生命周期流程

    路由层

    路由匹配
    	urlpatterns = [
    			url(r'^admin/', admin.site.urls),
    			url(r'test',views.test),
    			url(r'testadd',views.testadd)
    		]
    	url方法第一个参数是一个正则表达式
    	路由匹配按照正则匹配 一旦正则能够匹配到内容 会立刻执行对应的视图函数
    	不会再继续匹配了
    
    用户输入url不加最后的斜杠 django会默认自动加上    
    你可以在配置文件中指定是否开启该功能
    APPEND_SLASH = True/False
    

    无名分组

    无名分组
    	在路由匹配的时候给某段正则表达式加了括号
    	匹配的时候会将括号内正则表达式匹配到的内容当做位置参数传递给对应的视图函数
    	# 无名分组
    	url(r'^test/([0-9]{4})/',views.test)
    	# 视图函数
    	def index(request,args):
    		return HttpResponse('')
    

    有名分组

    有名分组
    	给一段正则表达式起一个别名
    	匹配的时候会将括号内正则表达式匹配到的内容当做关键字参数传递给对应的视图函数
    	# 有名分组
    	url(r'^test/(?P<year>\d+)/',views.test)
    	# 视图函数
    	def index(request,year):
    		...
    
    补充:	
    	# 无名有名能否混合使用   >>>    不能!!!
    	# url(r'^test/(\d+)/(?P<year>\d+)/', views.test),
    	# 虽然不能混合使用 但是同一种命名方式 可以使用多个
    	# url(r'^test/(\d+)/(\d+)/',views.test),
    	url(r'^test/(?P<xxx>\d+)/(?P<year>\d+)/',views.test),
    

    反向解析

    反向解析
    通过一些方法 能够得到一个结果 该结果可以访问到对应的url

    使用方式 
    		先给路由与视图函数对应关系 起一个名字
    			url(r'^testadd/',views.testadd,name='add')
    		前端解析
    			{% url 'add' %}
    		后端解析
    			from django.shortcuts import render,HttpResponse,redirect,reverse
    			reverse('add')
    

    无名分组反向解析

    # 无名分组反向解析
    			url(r'^testadd/(\d+)/',views.testadd,name='add')
    		前端解析
    			{% url 'add' 1 %}
    		后端解析
    			reverse('add',args=(12,))
    

    有名分组反向解析

    # 有名分组反向解析
    			url(r'^testadd/(?P<year>\d+)/',views.testadd,name='add')
    		前端解析
    			{% url 'add' 1 %}  # 推荐使用
    			{% url 'add' year= 1 %}  # 标准的
    		后端解析
    			reverse('add',args=(12,))
    			reverse('add',kwargs={'year':12})
    
    
    伪代码诠释
    	url(r'^edit_user/(\d+)/',views.edit_user,names='edit')
    	
    	前端:
    	{% for user_obj in user_queryset %}
    		<a href="edit_user/{{ user_obj.id }}/">编辑</a>
    		<a href="{% url 'edit' user_obj.id %}">编辑</a>
    	{% endfor %}
    	后端:
    	def edit_user(request,edit_id):
    		reverse('edit',args=(edit_id,))
    

    路由分发

    路由分发
    	当django项目比较庞大的时候 路由与视图函数对应关系较多
    	总路由代码太多冗长
    	考虑到总路由代码不好维护 django支持每个app都可以有自己的urls.py
    	并且总路由不再做路由与视图函数的对应关系 而仅仅只做一个分发任务的操作
    	
    	根据请求的不同 识别出当前请求需要访问的功能属于哪个app然后自动
    	下发到对应app里面的urls.py中 然后由app里面的urls.py做路由与视图函数的匹配
    	
    	不仅如此每个app除了可以有自己的urls.py之外 还可以有自己的static文件夹 templates模板文件
    	基于上面的特点 基于django分小组开发 会变得额外的简单
    	每个人只需要开发自己的app即可 之后只需要创建一个空的django项目
    	将多个人的app全部拷贝项目下 配置文件注册
    	总路由分发一次 
    
    需要一个分发的模块
    1.总路由
    	from django.conf.urls import url,include
    	# 简写
    	url(r'^app01/',include('app01.urls')),
    	url(r'^app02/',include('app02.urls'))
    2.子路由1
    	from django.conf.urls import url
        from app01 import views
    
        urlpatterns = [
        	url(r'^index/',views.index)
        ]
    3.子路由2
        from django.conf.urls import url
        from app02 import views
    
        urlpatterns = [
        	url(r'^index/',views.index)
        ]
    

    drf路由分发

    主路由:

    from django.conf.urls import url, include
    from django.contrib import admin
    
    urlpatterns = [
        url(r'^admin/', admin.site.urls),
        url(r'^api/', include('api.urls'))
    ]
    

    副路由:

    from django.conf.urls import url
    
    from . import views
    from django.views.static import serve
    from d_priect import settings
    urlpatterns = [
        url(r'users/$',views.UserAPIView.as_view()),
        url(r'users/(?P<pk>\d+)/$',views.UserAPIView.as_view()),
    	
        # 暴露文件
        url(r'^media/(?P<path>.*)', serve, {'document_root': settings.MEDIA_ROOT}),
    
    ]
    

    视图:

    注意:rest_framework需要先注册,在settings.py中:

    INSTALLED_APPS = [
    
    
        # drf框架的部分功能是依赖于注册后的,所有drf需要在app中注册
        'rest_framework',
    ]
    
    from rest_framework.views import APIView
    from rest_framework.response import Response
    
    class UserAPIView(APIView):
        def get(self,request,*args,**kwargs):
            return Response('get ok')
    
        def post(self,*args,**kwargs):
            return Response('post ok')
    

    名称空间

    为了防止多个app路由函数的名字重复,调用的时候就用名称空间。(不推荐)

    推荐方式:给app路由函数起名字的时候加上前缀app的名字,这样方式路由函数的名字就永远不会重复了

    名称空间(了解)
    	url(r'^app01/',include('app01.urls',namespace='app01'))
        url(r'^app02/',include('app02.urls',namespace='app02'))
    	后端解析
    	reverse('app01:index')
    	reverse('app02:index')
    	前端解析
    	{% url 'app01:index' %}
    	{% url 'app02:index' %}
    	# 在给路由与视图函数起别名的时候只需要保证永远不出现冲突的情况即可
    	# 通常情况下我们推荐期别名的时候加上当前应用的应用名前缀
    推荐:
    	url(r'^index/',views.index,name='app01_index')
    	url(r'^index/',views.index,name='app02_index')
    

    虚拟环境

    虚拟环境
    	我们想做到针对不同的项目 只安装项目所需要的功能模块
    	项目用不到的一概不装 来避免加载资源时的消耗
    	
    	如何创建虚拟环境
    	
    	虚拟环境就类似于一个纯净的python解释器环境
    	大白话 没创建一个虚拟幻境就类似于你重新下载一个python解释器
    	
    	虚拟环境不推荐你使用太多
    	学习阶段我们还是用本机的环境即可 将所有模块全部装到本机环境下
    

    有view的文件就是虚拟环境

    django版本区别

    django版本区别
    		路由层
    			1.X用的是url
    			2.X、3.X用的是path
    		
    		url第一个参数是一个正则表达式
    		而path第一个参数不支持正则表达式 写什么就匹配什么
    		如果你觉得path不好用 2.x、3.x给你提供了一个跟url一样的功能
    		re_path 等价于1.x里面的url功能
    		
    		虽然path不支持正则表达式 但是它给你提供了五种默认的转换器
    		str,匹配除了路径分隔符(/)之外的非空字符串,这是默认的形式
    		int,匹配正整数,包含0。
    		slug,匹配字母、数字以及横杠、下划线组成的字符串。
    		uuid,匹配格式化的uuid,如 075194d3-6885-417e-a8a8-6c931e272f00。
    		path,匹配任何非空字符串,包含了路径分隔符(/)(不能用?)
    		
    		比如:path('login/<int:year>/',login)
    		
    		除了默认的五种转换器之外 还支持你自定义转换器
    		class MonthConverter:
    		regex='\d{2}' # 属性名必须为regex
    
    		def to_python(self, value):
    			return int(value)
    
    		def to_url(self, value):
    			return value # 匹配的regex是两个数字,返回的结果也必须是两个数字
    

    伪静态

    伪静态
    	url以.html结尾 给人的感觉好像是这个文件是写死的 内容不会轻易的改变
    	伪静态
    	
    	为了提高你的网站被搜索引擎收藏的力度 提供网站的SEO查询效率
    	
    	但是 无论你怎么做优化 都抗不过RMB玩家
    

    视图层

    视图函数必须要返回一个HttpResponse对象
    一个视图函数(类),简称视图,是一个简单的Python 函数(类),它接受Web请求并且返回Web响应。
    
    响应可以是一张网页的HTML内容,一个重定向,一个404错误,一个XML文档,或者一张图片。
    
    无论视图本身包含什么逻辑,都要返回响应。代码写在哪里也无所谓,只要它在你当前项目目录下面。除此之外没有更多的要求了——可以说“没有什么神奇的地方”。为了将代码放在某处,大家约定成俗将视图放置在项目(project)或应用程序(app)目录中的名为views.py的文件中。
    

    三板斧

    1.HttpResponse  返回字符串
        return HttpResponse('字符串')
     
    2.render    返回html页面
        return render(request,'templates文件夹下的html文件名',{'xxx':'hello world'})
              页面上就可以通过{{xxx}}拿到hello world
            模板的渲染(将数据在后端按照模板语法放入html对应的位置)
    3.redirect  重定向
        return redirect(url)    # url可以是别人网站的全路径 也可以是自己网站的url后缀
        return redirect('/index')
        return redirect('https://www.mzitu.com')
    

    JsonResponse前后端交互数据格式

    观察源码可知:

    前后端交互的数据格式json

    因为前端返回的是一个HttpResponse对象,JsonResponse对象又是HttpResponse对象的子类。
    使用方法:
    	1.导入模块 JsonResponse
    		from django.http import JsonResponse
    	2.序列化非字典格式数据
    		kk=[1,2,3,4,5,'你好']
    		return JsonResponse(kk,safe=False)  # 序列化非字典格式数据 需要将safe改为False
        3.数据中的汉字不序列化
        	return JsonResponse(kk,safe=False,json_dumps_params={'ensure_ascii':False})
    

    form表单上传文件 后端如何获取

    前端:

    <form action="" method="post" enctype="multipart/form-data">
        <input type="file" name="myfile">
        <input type="submit">
    </form>
    

    后端获取:用 FILES

    def home(request):
        if request.method == 'POST':
            # 获取用户上传的文件数据
            print(request.FILES)  
            file_obj = request.FILES.get('myfile')  # 文件句柄,前端按钮<input type="file" name="myfile">
            print(file_obj.name)  # 获取文件名
            # 保存
            with open(file_obj.name,'wb') as f:
                    for line in file_obj:
                        f.write(line)
    
        return render(request,'home.html')
    
  • 相关阅读:
    QuartzQuartz定时任务
    jdbc模糊查询、分页查询、联合查询
    PreparedStatement
    web服务器简述
    JDBC基本操作
    RMI
    Http编程
    2020毕业季业务开发宝典
    程序设计流程图
    系统概要框图
  • 原文地址:https://www.cnblogs.com/guyouyin123/p/12158264.html
Copyright © 2011-2022 走看看