• 五、视图层(一)


    一、URLconf配置(正向传参)
    #### Django如何处理一个请求
    当一个用户通过网页发送一个请求给Django网站,Django执行过程如下:
    1. 首先访问项目下的settings.py文件中 ROOT_URLCONF = 'test1.urls'
    2. 执行项目包下的urls.py文件中的urlpatterns列表
    3. 执行应用包下的urls.py文件中的urlpatterns列表
    4. 根据匹配的url正则调用相应的视图函数/通用视图
    5. 如果没有匹配的正则,将会自动调用Django错误处理页面
    #### url函数配置方式
    - 方式1
    ```
    #student/urls.py
    #coding=utf-8
    from django.conf.urls import url
    from . import views
    urlpatterns=[
        url(r'^query$',views.queryAll)
    ]
    #student/views.py
    # -*- coding: utf-8 -*-
    from __future__ import unicode_literals
    from django.http import HttpResponse
    from django.shortcuts import render
    # Create your views here.
    def queryAll(request):
        return HttpResponse('hello world')
    #访问地址
    http://127.0.0.1:8000/student/query

    ```
    - 方式2:位置传参
    ```
    #student/urls.py
    #coding=utf-8
    from django.conf.urls import url
    from . import views
    urlpatterns=[
        url(r'^query$',views.queryAll),
        url(r'^query/(d{2})$',views.queryAll),
    ]

    #student/views.py
    # -*- coding: utf-8 -*-
    from __future__ import unicode_literals
    from django.http import HttpResponse
    from django.shortcuts import render
    # Create your views here.
    def queryAll(request,sno):
        print sno
        return HttpResponse('hello world')

    #访问地址
    http://127.0.0.1:8000/student/query/12
    ```
    - 方式3:关键字传参
    ```
    urlpatterns=[
        url(r'^query$',views.queryAll),
        url(r'^query/(d{2})$',views.queryAll),
        url(r'^query/(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/(?P<day>[0-9]{2})/$', views.queryAll),
    ]

    def queryAll(request,year,day,month):
        print year,month,day
        return HttpResponse('hello world')

    #访问地址
    http://127.0.0.1:8000/student/query/2008/10/12/   
    ```
    - 方式4:加载其他映射文件
    ```
    from django.conf.urls import include, url
    urlpatterns = [
        
        url(r'^community/', include('aggregator.urls')),
    ]
    ```
    - 方式5:传参(参数名必须保持一致)
    ```
    urlpatterns=[
        url(r'^query$',views.queryAll),
        url(r'^query/(d{2})$',views.queryAll),
        url(r'^query/(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/(?P<day>[0-9]{2})/$', views.queryAll),
        url(r'^query/(?P<num1>d{3})/$',views.queryAll,{'hello':'123'}),
    ]
     
    def queryAll(request,num1,hello):
        print num1,hello
        return HttpResponse('hello world')
       
    #访问地址  
    http://127.0.0.1:8000/student/query/888/
    ```
     
    二、URLConf配置 (反向传参)
    #### 逆向解析(防止硬编码)
    ```
    方式一
    ‘’‘’‘
    #student/urls.py
    from django.conf.urls import url
    from . import views
    urlpatterns=[
        url(r'^query$',views.queryAll),
        url(r'^query/(d{2})$',views.queryAll),
        url(r'^query/(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/(?P<day>[0-9]{2})/$', views.queryAll),
        url(r'^query/(?P<num1>d{3})/$',views.queryAll,{'hello':'123'}),
        url(r'^query1/([0-9]{4})/$', views.queryAll, name='hello'),
        url(r'^$', views.index_view),
    ]
    #student/views.py
    # -*- coding: utf-8 -*-
    from __future__ import unicode_literals
    from django.http import HttpResponse
    from django.shortcuts import render
    # Create your views here.
    def queryAll(request,num1):
        print num1
        return HttpResponse('hello world')
    #通过模板页面逆向访问
    def index_view(request):
        return render(request,'index.html')
    #通过Python代码逆向访问
    def index_view(request):
        # return render(request,'index.html')
        return HttpResponseRedirect(reverse('hello',args=(2018,)))
        
    #templates/index.html
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
        <a href="{% url 'hello' 2008 %}">访问</a>
    </body>
    </html>
     
    ```
      方式2
    ```
    #项目包/urls.py
    from django.conf.urls import url, include
    from django.contrib import admin
    urlpatterns = [
        url(r'^admin/', admin.site.urls),
        url(r'^student/', include('student.urls',namespace='stu',app_name='student')),
    ]
    #应用包/urls.py
    #coding=utf-8
    from django.conf.urls import url
    from . import views
    urlpatterns=[
        url(r'^$', views.Index.as_view()),
        url(r'^query2/',views.Login.as_view(),name='login')
    ]

    #应用包/views.py
    # -*- coding: utf-8 -*-
    from __future__ import unicode_literals
    from django.http import HttpResponse, HttpResponseRedirect
    from django.shortcuts import render
    from django.urls import reverse
     

    from django.views import View
    class Index(View):
        def get(self,request):
            return render(request,'index.html')

    class Login(View):
        def get(self,request):
            return HttpResponse('hello')

    #templates/index.html
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
        <a href="{% url 'stu:login' %}">访问</a>
    </body>
    </html>

    ```
     三、文件上传
    #### Django文件上传
    #### 需求
    1. 完成学生信息注册操作
    2. 将学生信息入库
    3. 将上传文件存放至项目下media文件夹下
    4. 显示所有学生信息
    #### 创建模型类
    ```
    class Student(models.Model):
        sno = models.AutoField(primary_key=True)
        sname = models.CharField(max_length=30)
        photo = models.ImageField(upload_to='imgs')
        class Meta:
            db_table = 't_stu'
        def __unicode__(self):
       
            return u'Student:%s'%self.sname

    ```
     
    #### settings.py文件中文件上传相关设置
    ```
    INSTALLED_APPS = [
        ...
        'stu'
    ]
    DATABASES = {
        'default': {
            'ENGINE': 'django.db.backends.sqlite3',
            'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
        }
    }
     
    MEDIA_URL = '/media/'
    MEDIA_ROOT = os.path.join(BASE_DIR,'media')
    ```
    #### 映射数据库表
    ```
    #在终端中敲命令
    python manage.py makemigrations stu
    python manage.py migrate

    ```

    #### 配置URL
    - test13/urls.py
    ```
    #coding=utf-8
    from django.conf.urls import url, include
    from django.contrib import admin
    from test13.settings import DEBUG, MEDIA_ROOT
    urlpatterns = [
        url(r'^admin/', admin.site.urls),
        url(r'^stu/', include('stu.urls')),
    ]
    #配置路由读取后台上传文件
    from django.views.static import serve
    if DEBUG:
        urlpatterns+=url(r'^media/(?P<path>.*)/$', serve, {"document_root": MEDIA_ROOT}),

    ```
    - stu/urls.py
    ```
    #coding=utf-8
    from django.conf.urls import url
    import views
    urlpatterns=[
        url(r'^$',views.index_view),
        url(r'^upload1/$',views.upload1_view),
        url(r'^showall/$',views.showall_view),
    ]
    ```
    #### 创建视图
    - stu/views.py
    ```
    # -*- coding: utf-8 -*-
    from __future__ import unicode_literals
    from django.http import HttpResponse, HttpResponseRedirect
    from django.shortcuts import render
    # Create your views here.
    from stu.models import Student
    #显示注册页面
    def index_view(request):
        return render(request,'index.html')
         
    #django文件上传
    def upload1_view(request):
        #1.获取请求参数
        sname = request.POST.get('sname')
        photo = request.FILES.get('photo')
        #2.插入数据库
        stu = Student.objects.create(sname=sname,photo=photo)
        #3.判断是否注册成功
        if stu:
            return HttpResponse('注册成功!')
        return HttpResponseRedirect('/stu/')
    #显示所有学生信息
    def showall_view(request):
        #查询所有学生信息
        stus = Student.objects.all()
        return render(request,'show.html',{'stus':stus})  

    ```

    #### 创建模板
    - templates/index.html
    ```
        <form action="/stu/upload1/" method="post" enctype="multipart/form-data">
            {% csrf_token %}
            <p>
                <label for="sname">姓名:</label><input type="text" name="sname" id="sname"/>
            </p>
            <p>
                <label for="photo">头像:</label><input type="file" name="photo" id="photo"/>
            </p>
            <p>
                &emsp;&emsp;<input type="submit" value="注册" />
            </p>
        </form>
    ```
    - templates/show.html
    ```
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <style>
            img{
                200px;
            }
        </style>
    </head>
    <body>
        <table border="1" width="500px" cellspacing="0">
            <tr>
                <th>编号</th>
                <th>姓名</th>
                <th>头像</th>
                <th>操作</th>
            </tr>
            {% for stu in stus %}
                <tr>
                    <td>{{ forloop.counter }}</td>
                    <td>{{ stu.sname }}</td>
                    <td><img src="{{ MEDIA_URL }}{{ stu.photo }}"/></td>
                    <td>操作</td>
                </tr>

            {% endfor %}

        </table>
    </body>
    </html>
    ```
    #### 头像读取相关settings.py文件中的设置
    ```
    TEMPLATES = [
        {
            'BACKEND': 'django.template.backends.django.DjangoTemplates',
            'DIRS': [os.path.join(BASE_DIR, 'templates')]
            ,
            'APP_DIRS': True,
            'OPTIONS': {
                'context_processors': [
                    'django.template.context_processors.debug',
                    'django.template.context_processors.request',
                    'django.contrib.auth.context_processors.auth',
                    'django.contrib.messages.context_processors.messages',
                    'django.template.context_processors.media'#配置这句话
                ],
            },
        },
    ]
    ```
     
    四、文件下载
     
    #### 配置URL
    ```
    #coding=utf-8
    from django.conf.urls import url
    from . import views
    urlpatterns=[
        url(r'^$', views.Index.as_view()),
        url(r'^stulist/$', views.StuList.as_view()),
        url(r'^download/$', views.Download.as_view()),
    ]
    ```

    #### 创建视图
    ```
    class Download(View):
        def get(self,request):
            #获取文件存放位置
            filepath = request.GET.get('photo','')
            #获取文件名
            filename = filepath[filepath.rindex('/')+1:]
            #获取文件绝对路径
            path =  os.path.join(os.getcwd(),'media',filepath.replace('/','\'))
            with open(path,'rb') as fr:
                response = HttpResponse(fr.read())
                response['Content-Type']='image/png'
                #预览模式
                response['Content-Disposition']='inline;filename='+filename
                #附件模式
                # response['Content-Disposition']='attachment;filename='+filename
            return response
    ```
     
    #### 文件名中文情况
    ```
    from django.utils.encoding import escape_uri_path
    response['Content-Disposition'] = "attachment; filename*=utf-8''{}".format(escape_uri_path(file_name))

    ```
     
     
  • 相关阅读:
    Ajax 的 GET 和 POST 模式
    AJax中post与get请求注意事项
    代理模式 (Proxy)
    装饰模式 (Decoratory)
    抽象工厂模式( Abstract Factory )
    单例模式(Singleton)
    原型设计模式
    Intro.js的简介和用法
    mysql 分片
    数据分片(二)如何为数据分片
  • 原文地址:https://www.cnblogs.com/dangjingwei/p/12872034.html
走看看 - 开发者的网上家园