Advanced a Django

Create table relationships

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

One to one relationship building: 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')

Many relationships established: 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')  # 书籍和作者是多对多关系

To-many relationship building: 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 request lifecycle process

Routing layer

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

Unknown group

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

Famous grouping

有名分组
    给一段正则表达式起一个别名
    匹配的时候会将括号内正则表达式匹配到的内容当做关键字参数传递给对应的视图函数
    # 有名分组
    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),

Reverse lookup

Reverse analysis
by a number of approaches to be a result of the result url to access the corresponding

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

Unknown Packet reverse lookup

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

Famous grouping reverse lookup

# 有名分组反向解析
            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,))

Route distribution

路由分发
    当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)
    ]

Namespaces

App name in order to prevent multiple routing functions repeat, when called on by name space. (Not recommended)

Recommended way: from the name of the function to the app route when the prefix plus the name of the app's name in such a way routing function will never be repeated

名称空间(了解)
    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')

Virtual Environment

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

There is the view of the virtual environment file

django version differences

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是两个数字,返回的结果也必须是两个数字

Pseudo-static

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

View layer

视图函数必须要返回一个HttpResponse对象
一个视图函数(类),简称视图,是一个简单的Python 函数(类),它接受Web请求并且返回Web响应。

响应可以是一张网页的HTML内容,一个重定向,一个404错误,一个XML文档,或者一张图片。

无论视图本身包含什么逻辑,都要返回响应。代码写在哪里也无所谓,只要它在你当前项目目录下面。除此之外没有更多的要求了——可以说“没有什么神奇的地方”。为了将代码放在某处,大家约定成俗将视图放置在项目(project)或应用程序(app)目录中的名为views.py的文件中。

Three tricks

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')

Front and rear ends interaction data format JsonResponse

Observation source code can be seen:

The front end of the interactive data format 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})

How to get the backend file upload form form

front end:

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

Get the back end: with 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')

Guess you like

Origin www.cnblogs.com/guyouyin123/p/12158264.html