缓缓飘落的树叶像思念

今日内容
orm表关系如何建立
多对多
一对多
一对一
换位思考 先站在一张表上面分析 然后再站在另一张分析

    本周大作业
        图书管理系统
        
        一对多 外键字段建在 多的那一方
        多对多 多对多的外键关系需要建立第三章来专门处理


图书表


出版社表


作者表

        from django.db import models

        # Create your models here.
        # 先不要考虑外键关系  先创基表
        class Book(models.Model):
            title = models.CharField(max_length=32)
            # 小数总共八位 小数占两位
            price = models.DecimalField(max_digits=8,decimal_places=2)

            # 书跟出版社是一对多 并且书是多的一方 所以外键字段健在书表中
            publish_id = models.ForeignKey(to='Publish')  # to用来指代跟哪张表有关系 默认关联的就是表的主键字段
            """
            一对多外键字段 创建的时候 同步到数据中 表字段会自动加_id后缀
            
            如果你自己加了_id 我orm头铁 再在后面加一个_id
            
            所以你在写一对多外键字段的时候 不要自作聪明的加_id
            """



            # 书跟作者是多对多的关系 外键字段建在任意一方都可以  但是建议你建在查询频率较高的那一方
            author = models.ManyToManyField(to='Author')  # django orm会自动帮你创建书籍 和作者的第三张关系表
            # author这个字段是一个虚拟字段 不能在表中展示出来 仅仅只是起到一个高速orm 建第三章表的关系的作用


        class Publish(models.Model):
            title = models.CharField(max_length=32)
            email = models.EmailField()


        class Author(models.Model):
            name = models.CharField(max_length=32)
            age = models.IntegerField()
            # 一对一的表关系 外键字段建在任意一方都可以    但是建议你建在查询频率较高的那一方

            author_detail = models.OneToOneField(to='Author_detail')  # fk + unique
            """
            一对一外键字段 创建的时候 同步到数据中 表字段会自动加_id后缀

            如果你自己加了_id 我orm头铁 再在后面加一个_id

            所以你在写一对一外键字段的时候 不要自作聪明的加_id
            """

        class Author_detail(models.Model):
            phone = models.BigIntegerField()
            addr = models.CharField(max_length=32)  

django请求生命周期流程图
    是你后期复习django最好的方式
    
urls.py 路由层
    url第一个参数是一个正则表达式 只要该正则表达式能够匹配到内容
    就会立刻执行后面的视图函数 而不再往下继续匹配了





路由匹配
# 取消django自动让浏览器加斜杠的功能
APPEND_SLASH = False # 该参数默认是True

    from app01 import views



    urlpatterns = [
        url(r'^admin/', admin.site.urls),  # url第一个参数是一个正则表达式
        url(r'^test/$', views.test),  # 一旦正则表达式能够匹配到内容 会立刻结束匹配关系 直接执行后面对应的函数
        url(r'^testadd/$', views.testadd),
    ]
    # django匹配路由的规律
    # 不加斜杠 先匹配一次试试 如果匹配不上 会让浏览器重定向 加一个斜杠再来一次 如果还匹配不上 才会报错
    """
    路由匹配值匹配url部分
    不匹配?后面的get携带的参数
    """

无名分组:将分组内正则表达式匹配到的内容当做位置参数传递给视图函数
    url(r'^test/([0-9]{4})/', views.test)
    test() takes 1 positional argument but 2 were given
    
    # 当你的路由中有分组的正则表达式  那么在匹配到内容
    # 执行视图函数的时候 会将分组内正则表达式匹配到的内容当做位置参数传递给视图函数  test(request,分组内正则表达式匹配到的内容)


有名分组:会将分组内的正则表达式匹配到的内容当做关键字参数传递给视图函数
url(r'^testadd/(?P \d+)/', views.testadd),

    testadd() got an unexpected keyword argument 'year'
    
    # 当你的路由中有分组并且给分组起了别名 那么在匹配内容的时候
    # 会将分组内的正则表达式匹配到的内容当做关键字参数传递给视图函数  testadd(request,year=分组内的正则表达式匹配到的内容)

利用有名个无名分组 我们就可以在调用视图函数之前给函数传递额外的参数
疑问:无名和有名能否混合使用???

url(r'^index/(\d+)/(?P<year>\d+)/', views.index),

不能混合使用!!!
但是同一种分组的情况下 可以使用多次
无名可以有多个
有名可以有多个
但是就是不能混合使用
        url(r'^index/(\d+)/(\d+)/', views.index),
        url(r'^index/(?P<args>\d+)/(?P<year>\d+)/', views.index),

反向解析
    """
    根据一个别名 动态解析出一个结果 该结果可以直接访问对应的url
    """
    第一种情况
        路由中没有正则表达式 直接是写死的
        url(r'^home/', views.home,name='xxx'),  # 给路由与视图函数对应关系起别名
        
        前端反向解析
            {% url 'xxx' %}
        
        后端反向解析
            from django.shortcuts import render,HttpResponse,redirect,reverse
            url = reverse('xxx')
    
    第二种情况
        无名分组的反向解析 在解析的时候 你需要手动指定正则匹配的内容是什么
        url(r'^home/(\d+)/', views.home,name='xxx'),  # 给路由与视图函数对应关系起别名
        
        前端反向解析
            <p><a href="{% url 'xxx' 12 %}">111</a></p>
            <p><a href="{% url 'xxx' 1324 %}">111</a></p>
            <p><a href="{% url 'xxx' 14324 %}">111</a></p>
            <p><a href="{% url 'xxx' 1234 %}">111</a></p>
        
        后端反向解析
                url = reverse('xxx',args=(1,))
                url1 = reverse('xxx',args=(3213,))
                url2 = reverse('xxx',args=(2132131,))
        # 手动传入的参数 只需要满足能够被正则表达式匹配到即可
    
    第三种情况
        有名分组的反向解析 在解析的时候 你需要手动指定正则匹配的内容是什么
        有名分组的反向解析可以跟无名分组一样
        但是最最正规的写法
        url(r'^home/(?P<year>\d+)/', views.home,name='xxx'),  # 给路由与视图函数对应关系起别名
        
        前端
            # 可以直接用无名分组的情况
            <p><a href="{% url 'xxx' 12 %}">111</a></p>
            # 你也可以规范写法
            <p><a href="{% url 'xxx' year=1232 %}">111</a></p>  # 了解即可
        
        后端
            # 可以直接用无名分组的情况
            url = reverse('xxx',args=(1,))
            # 你也可以规范写法
            url = reverse('xxx',kwargs={'year':213123})  # 了解即可
        
        以编辑功能为例
            url(r'^edit_user/(\d+)/',views.edit_user,name='edit')
            
            def edit_user(request,edit_id):
                # edit_id就是用户想要编辑数据主键值
                pass
            
            {% for user_obj in user_list %}
            <a href='/edit_user/{{user_obj.id}}/'>编辑</a>
            <a href='{% url 'edit' user_obj.id %}'>编辑</a>
            {% endfor %}


今日作业
用无名有名分组 加上反向解析完成用户的编辑功能
尝试着写图书列表的增删改查

路由分发(******)
    前提
        在django中所有的app都可以有自己独立的urls.py  templates static
        正是由于上面的特点 你用django开发项目就能够完全做到多人分组开发 互相不干扰
        每个人只开发自己的app
        小组长只需要将所有人开发的app整合到一个空的django项目里面
        然后在settings配置文件注册 再利用路由分发将多个app整合到一起即可完成大项目的拼接
        
    路由分发解决的就是项目的总路由匹配关系过多的情况
    
    使用路由分发 会将总路由不再做匹配的活 而仅仅是做任务分发(请求来了之后 总路由不做对应关系
    只询问你要访问哪个app的功能 然后将请求转发给对应的app去处理
    )
    
    from app01 import urls as app01_urls
    from app02 import urls as app02_urls


    urlpatterns = [
        url(r'^admin/', admin.site.urls),  # url第一个参数是一个正则表达式
        # 路由分发
        url(r'^app01/',include(app01_urls)),  # 路由分发需要注意的实现 就是总路由里面不能以$结尾
        url(r'^app02/',include(app02_urls)),
    ]
    
    # 子路由
    from django.conf.urls import url
    from app01 import views


    urlpatterns = [
       url('^reg/',views.reg)
    ]


from django.conf.urls import url
from app02 import views

    urlpatterns = [
       url('^reg/',views.reg)
    ]

    最省事的写法(******)
    url(r'^app01/',include('app01.urls')),
    url(r'^app02/',include('app02.urls'))

名称空间
    当多个app中出现了起别名冲突的情况 你在做路由分发的时候 可以给每一个app创建一个名称空间
    然后在反向解析的时候 可以选择到底去哪个名称空间中查找别名
    
        url(r'^app01/',include('app01.urls',namespace='app01')),
        url(r'^app02/',include('app02.urls',namespace='app02'))
        
        # 后端
        print(reverse('app01:reg'))
        print(reverse('app02:reg'))
        # 前端
        <a href="{% url 'app01:reg' %}"></a>
        <a href="{% url 'app02:reg' %}"></a>
    
    其实上面的名称空间知识点可以完全不用 你只需要保证起别名的时候 在整个django项目中不冲突即可
        参考建议
            起别名的时候统一加上应用名前缀
                urlpatterns = [
                    url(r'^reg/',views.reg,name='app02_reg')
                ]
                
                urlpatterns = [
                   url('^reg/',views.reg,name='app01_reg')
                ]

伪静态
    将一个动态网页伪装成一个静态网页 以此来挺好搜索引擎SEO查询频率和搜藏力度
    
    所谓的搜索引擎其实就是一个也别巨大的爬虫程序
    
    优化的再厉害还是抵不过RMB玩家


虚拟环境
给每一个项目 装备该项目所需要的模块 不需要的模块一概不装

    每创建一个虚拟环境就类似于你重新下载了一个纯净python解释器
    之后该项目用到上面 你就装什么(虚拟环境一台机器上可以有N多个)
    
    不要在你的机器上无限制创建虚拟环境
    
django版本区别
    django1.X  django2.X
    
    urls.py中路由匹配的方法有区别
    django2.X用的是path
        urlpatterns = [
            path('admin/', admin.site.urls),
        ]
    django1.X用的是url
        urlpatterns = [
            url(r'^reg.html',views.reg,name='app02_reg')
        ]
    # 区别 django2.X里面path第一个参数不是正则也不支持正则 写什么就匹配什么
    # 虽然path不支持正则 感觉也好用 django2.X还有一个re_path的方法 该方法就是你django1.X里面url
    
    # 虽然path支持 但是它提供了五种转换器  能够将匹配到的数据自动转黄成对应的类型
    
    # 除了有默认五种转换器之外 还支持你自定义转换器


路由层学完了



视图层

form表单上传文件 后端如何获取文件
form表达传文件需要注意的事项
    1.method必须改成post
    2.enctype该成formdata格式
前期你在使用post朝后端发请求的时候 需要去settings配置文件中注释掉一个中间件csrf




JsonResponse

猜你喜欢

转载自www.cnblogs.com/jimGraymane/p/11931155.html