溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶(hù)服務(wù)條款》

django 進(jìn)階之view layer

發(fā)布時(shí)間:2020-10-23 10:47:48 來(lái)源:網(wǎng)絡(luò) 閱讀:1160 作者:長(zhǎng)跑者1號(hào) 欄目:編程語(yǔ)言

一 基本環(huán)境

1 環(huán)境處理

mkdir  djanad
cd djanad/
pyenv   virtualenv 3.6.5  djanad
pyenv  local  djanad

結(jié)果如下

django 進(jìn)階之view layer

2 創(chuàng)建django和基本配置

 pip install  django==2.1
django-admin startproject  demo .
django-admin  startapp  app

結(jié)果如下

django 進(jìn)階之view layer

數(shù)據(jù)庫(kù)配置如下

django 進(jìn)階之view layer

基本時(shí)區(qū)和mysql配置及相關(guān)時(shí)區(qū)配置請(qǐng)看django基礎(chǔ)

https://blog.51cto.com/11233559/2444627

啟動(dòng)結(jié)果如下

django 進(jìn)階之view layer

二 view基本使用

1 view中使用模板

1 概述

django內(nèi)置了自己的模板引擎,和jinjia 很像,使用簡(jiǎn)單

使用 Template 進(jìn)行定義模板,使用Context 將數(shù)據(jù)導(dǎo)入到該模板中,其導(dǎo)入默認(rèn)使用字典

django 進(jìn)階之view layer

2 環(huán)境準(zhǔn)備

1 創(chuàng)建models

django 默認(rèn)會(huì)去到app_name/templates下尋找模板,這是settings中的默認(rèn)設(shè)置,默認(rèn)會(huì)去app_name/static找那個(gè)尋找靜態(tài)文件(css,js,jpg,html)等


在 app/models.py 中創(chuàng)建數(shù)據(jù)庫(kù)表模板,具體配置如下:

from django.db import models

# Create your models here.
# 問(wèn)題
class Question(models.Model):
    question_text = models.CharField(max_length=200)
    pub_date = models.DateTimeField('date published')

    def __str__(self):
        return self.question_text

# 選擇
# 配置選擇為問(wèn)題的外鍵,并配置選擇的內(nèi)容和選擇的起始值
class Choice(models.Model):
    question = models.ForeignKey(Question, on_delete=Question)
    choice_text = models.CharField(max_length=200)
    votes = models.IntegerField(default=0)

    def __str__(self):
        return self.choice_text
2 執(zhí)行生成遷移文件和遷移并查看
 python manage.py   makemigrations

 python manage.py   migrate

結(jié)果如下

django 進(jìn)階之view layer

3 添加數(shù)據(jù)進(jìn)入表中

創(chuàng)建后臺(tái)登陸用戶(hù),設(shè)置用戶(hù)名為admin,密碼為admin@123

django 進(jìn)階之view layer

4 將model中的模型添加進(jìn)入django admin 后臺(tái)管理界面

app/admin.py中添加

# Register your models here.
from django.contrib import admin
from .models import Question, Choice

# Register your models here.
class ChoiceInline(admin.TabularInline):
    model = Choice
    extra = 3

class QuestionAdmin(admin.ModelAdmin):
    fieldsets = [
        (None, {'fields': ['question_text']}),
        ('Date information', {'fields': ['pub_date'], 'classes': ['collapse']}),
    ]
    inlines = [ChoiceInline]
    list_display = ('question_text', 'pub_date')

admin.site.register(Choice)
admin.site.register(Question, QuestionAdmin)

url : localhost:port/admin/

5 登陸后臺(tái)并添加數(shù)據(jù)如下

django 進(jìn)階之view layer

django 進(jìn)階之view layer

6 配置靜態(tài)文件

demo/setting.py 中配置添加

STATICFILES_DIRS = [
    os.path.join(BASE_DIR, 'static')
]

項(xiàng)目中創(chuàng)建static 并上傳圖片django.jpg

django 進(jìn)階之view layer

7 配置 url

demo/urls.py中配置如下

from django.conf.urls import url, include
from django.contrib import admin

urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^app/', include("app.urls",namespace="app")),  #此處配置名稱(chēng)空間,用于處理后面的翻轉(zhuǎn)
]
8 app中創(chuàng)建 urls.py 文件,內(nèi)容如下
from django.conf.urls import url, include
from . import views

urlpatterns = [
    url(r'^index/$', views.index, name="index"), # name 指定名稱(chēng),
]

django 進(jìn)階之view layer

3 view 使用

1 在view中直接嵌入模板,結(jié)果如下
from django.shortcuts import render
from django.template import Template, Context
from . import models
from django.http import HttpResponse

# Create your views here.

def index(request):
    lastes_question_list = models.Question.objects.order_by('-pub_date')[:5]
    template = Template("""
    <img  src="/static/django.jpg">
    {%  if lastes_question_list %}
    <ul>
    {% for question  in  lastes_question_list %}
    <li>  <a  href="/app/ {{question.id}}/"> {{ question.question_text }} </a> </li> 
    {% endfor %}
    </ul>
    {% endif %}
    """)
    context = Context({"lastes_question_list": lastes_question_list})
    return HttpResponse(template.render(context))

訪問(wèn)配置,結(jié)果如下

django 進(jìn)階之view layer

2 使用html 模板如下

django 進(jìn)階之view layer

index 代碼如下

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>測(cè)試數(shù)據(jù)</title>
</head>
<body>
<img src="/static/django.jpg">
{% if lastes_question_list %}
<ul>
    {% for question in lastes_question_list %}
    <li>
        <a href="/app/{{question.id}}/"> {{question.question_text}} </a>
    </li>
    {% endfor %}
</ul>

{% endif%}
</body>
</html>

app/view.py 中代碼如下

from . import models
from django.http import HttpResponse
from django.template import loader

# Create your views here.
def index(request):
    lastes_question_list = models.Question.objects.order_by('-pub_date')[:5]
    template = loader.get_template("app/index.html")
    context = {"lastes_question_list": lastes_question_list}
    return HttpResponse(template.render(context))
3 index.html不變,app/view 修改
from . import models
from django.shortcuts import render

# Create your views here.
def index(request):
    lastes_question_list = models.Question.objects.order_by('-pub_date')[:5]
    context = {"lastes_question_list": lastes_question_list}
    return render(request, template_name="app/index.html", context=context)
4 去掉static 和 url中的硬編碼及反向解析

根據(jù)根路由中注冊(cè)的namespace和子路由中注冊(cè)的name來(lái)動(dòng)態(tài)獲取路徑。在模板中使用"{% url namespace:name %}"
如果攜帶位置參數(shù)
“{% url namespace:name args %}"
如果攜帶關(guān)鍵字參數(shù)
“{% url namespace:name k1=v1 k2=v2 %}"


配置 詳情頁(yè)面添加數(shù)據(jù)

app/view.py 中添加數(shù)據(jù)如下

from . import models
from django.shortcuts import render

# Create your views here.
def index(request):
    lastes_question_list = models.Question.objects.order_by('-pub_date')[:5]
    context = {"lastes_question_list": lastes_question_list}
    return render(request, template_name="app/index.html", context=context)

def detal(request, question_id):
    detal = models.Question.objects.get(pk=question_id)
    context = {"detal": detal}
    return render(request, template_name="app/detal.html", context=context)

app/urls.py中如下


from django.conf.urls import url, include
from . import views

urlpatterns = [
    url(r'^index/$', views.index, name="index"),
    url(r'^(?P<question_id>[0-9]+)/$', views.detal, name="detal"),# name 指定名稱(chēng),用于后面的反向解析
]

]

詳情頁(yè)html 配置如下

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>測(cè)試數(shù)據(jù)</title>
</head>
<body>
{% if detal %}
<h2>{{ detal.question_text }}</h2>
{% for question in detal.choice_set.all %}
<li>
    {{ question.votes }}
    {{ question.choice_text }}
</li>
{% endfor %}
{% endif %}

</body>
</html>

index.html 修改如下

<!DOCTYPE html>
<html lang="en">
<head>
    {% load static %}
    <meta charset="UTF-8">
    <title>測(cè)試數(shù)據(jù)</title>
</head>
<body>
<img src="{% static  'django.jpg'%}">
{% if lastes_question_list %}
<ul>
    {% for question in lastes_question_list %}
    <li>
        <a href="{% url 'detal' question.id  %}"> {{question.question_text}} </a>
    </li>
    {% endfor %}
</ul>

{% endif%}
</body>
</html>

2 針對(duì)上述項(xiàng)目實(shí)現(xiàn)投票機(jī)制

1 修改detal 結(jié)果如下

此處的app:vote 是對(duì)應(yīng)的namespace 和 name ,及名稱(chēng)空間和名稱(chēng)

<!DOCTYPEhtml>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>測(cè)試數(shù)據(jù)</title>
</head>
<body>
<h2>{{ detal.question_text }}</h2>
<p>
    <strong>{{error_message}}</strong>
</p>
<form action="{% url 'app:vote' detal.id %}" method="post">
    {% for choice in detal.choice_set.all %}
    <input type="radio" name="choice" id="choice {{ forloop.counter }}" value="{{ choice.id }}"/>
    <label for="choice {{ forloop.counter }}"> {{ choice.choice_text }} </label>
    <br/>
    {% endfor %}
    <input type="submit" value="投票"/>
</form>

</body>
</html>

2 app/views.py

from . import models
from django.http import HttpResponseRedirect
from django.shortcuts import render, get_object_or_404, reverse

# Create your views here.
def index(request):
    lastes_question_list = models.Question.objects.order_by('-pub_date')[:5]
    context = {"lastes_question_list": lastes_question_list}
    return render(request, template_name="app/index.html", context=context)

# 詳情頁(yè)面
def detal(request, question_id):
    detal = models.Question.objects.get(pk=question_id)
    context = {"detal": detal}
    return render(request, template_name="app/detal.html", context=context)

# 投票結(jié)果顯示
def vote(request, question_id):
    question = get_object_or_404(models.Question, pk=question_id)
    if request.method == "POST":
        choice_id = request.POST.get('choice', 0)
        try:
            selected_choice = question.choice_set.get(pk=choice_id)
        except  models.Choice.DoesNotExist:
            return render(request, 'app/detal.html', {
                'qestion': question,
                "error_message": "You didn't select  a  choice",
            })
        else:
            selected_choice.votes += 1
            selected_choice.save()
            return HttpResponseRedirect(reverse('app:results', args=(question.id,)))

# 投票結(jié)果顯示
def results(request, question_id):
    question = get_object_or_404(models.Question, pk=question_id)
    print(question, type(question))
    return render(request, 'app/results.html', {"question": question})

3 templates/app/results.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title></title>
</head>
<body>
<h2> {{ question.question_text }} </h2>
<h2> 測(cè)試 </h2>

<ul>
    {% for choice in question.choice_set.all %}

    <li>
        {{ choice.choice_text }} -- {{ choice.votes }} vote {{ choice.votes |pluralize }}
    </li>
    {% endfor %}
</ul>

</body>
</html>

4 投票程序結(jié)果如下:

django 進(jìn)階之view layer

3 錯(cuò)誤頁(yè)面處理

1 基本頁(yè)面處理

def test(request):
    # return HttpResponse('Not Found', status=404)
    return HttpResponseNotFound('Not Found')

urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^app/', include("app.urls"), {"question_id": 1}),  # 此處配置直接捕獲question_id 進(jìn)行處理
    url(r'^test/$', test)
]

上述兩種返回錯(cuò)誤方式結(jié)果相同

2 自定義錯(cuò)誤視圖

在url中導(dǎo)入,在其他頁(yè)面使用即可
在 demo/urls.py中導(dǎo)入

from django.conf.urls import url, include
from django.contrib import admin
from django.http import HttpResponse, HttpResponseNotFound

def test(request):
    return HttpResponse('Not Found', status=404)

handler404 = 'demo.views.my_custom_page_not_found_view'
handler500 = 'demo.views.my_custom_error_found_view'
handler403 = 'demo.views.my_custom_permission_denied_view'
handler400 = 'demo.views.my_custom_bad_request_request_view'

urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^app/', include("app.urls")),  # 此處配置直接捕獲question_id 進(jìn)行處理
    url(r'^test/$', test)
]

demo/views.py中配置如下

from django.http import HttpResponse

def my_custom_page_not_found_view(request):
    return HttpResponse("頁(yè)面不存在", status=404)

def my_custom_error_found_view(request):
    return HttpResponse("服務(wù)器錯(cuò)誤", status=500)

def my_custom_permission_denied_view(request):
    return HttpResponse("拒絕訪問(wèn)", status=403)

def my_custom_bad_request_request_view(request):
    return HttpResponse("請(qǐng)求錯(cuò)誤", status=400)

此處需要將demo/setting.py 中的DEBUG修改為False,才會(huì)出現(xiàn)此處定義的情況

django 進(jìn)階之view layer

結(jié)果如下

django 進(jìn)階之view layer

django 進(jìn)階之view layer

4 相關(guān)函數(shù)

1 render函數(shù)

用于渲染模板和傳遞參數(shù)

def render(request, template_name, context=None, content_type=None, status=None, using=None):
    """
    Returns a HttpResponse whose content is filled with the result of calling
    django.template.loader.render_to_string() with the passed arguments.
    """
    content = loader.render_to_string(template_name, context, request, using=using)
    return HttpResponse(content, content_type, status)

選項(xiàng):

request : 請(qǐng)求參數(shù)

template_name:對(duì)應(yīng)的html模板名稱(chēng)

context:渲染模板的context字典,默認(rèn)是空 {}

content_type : Response MIME type,默認(rèn)使用DEFAULT_CONTENT_TYPE 設(shè)置

2 redirect 函數(shù)

用于頁(yè)面跳轉(zhuǎn)

def redirect(to, *args, **kwargs):
    pass 

選項(xiàng)

to :
此選項(xiàng)可以是
1 模塊
2 視圖名稱(chēng)
3 absolute或者回調(diào) url

perments 是否永久重定向

為 True 表示永久重定向,否則表示臨時(shí)重定向

3 get_object_or_404 函數(shù)

當(dāng)對(duì)象不存在時(shí)返回特定頁(yè)面404

def get_object_or_404(class, *args, **kwargs):
    pass 

第一個(gè)參數(shù): 可為Model中對(duì)應(yīng)的數(shù)據(jù)庫(kù)表類(lèi),后面可為對(duì)應(yīng)的過(guò)濾方法

    question = get_object_or_404(models.Question, pk=question_id)

當(dāng)對(duì)象執(zhí)行成功時(shí),返回對(duì)應(yīng)的值,否則返回404 錯(cuò)誤

4 get_list_or_404 函數(shù)

當(dāng)對(duì)象不存在時(shí)返回特定頁(yè)面404

    question = get_list_or_404(models.Question, pk=question_id)

5 裝飾器

require_http_methods(request_method_list)
用于限制請(qǐng)求類(lèi)型,在此中以列表的形式顯示


require_GET()
用于限制請(qǐng)求類(lèi)型為GET請(qǐng)求


require_POST()
用于限制請(qǐng)求類(lèi)型為POST 請(qǐng)求


require_safe()
用于限制安全的請(qǐng)求,如get和head


gzip_page()
用于啟用gzip壓縮功能


cache_control(**kwargs)
緩存相關(guān)函數(shù)


never_cache()
用于配置永久不緩存


login_required()
用于處理登錄后的用戶(hù)才能訪問(wèn)對(duì)應(yīng)的屬性

三 urlconf

1 django 路由匹配概述

1 項(xiàng)目啟動(dòng)后根據(jù) setting ROOT_URLCONF 決定跟URLconf,默認(rèn)是object中的urls.py

2 它是django.conf.urls.url()實(shí)例的一個(gè)python 列表

3 django 依次匹配每個(gè)URL模式,在于請(qǐng)求的URL匹配的第一個(gè)模式停下來(lái)。

4 一旦其中的一個(gè)正則表達(dá)式匹配上,django將導(dǎo)入并調(diào)用給出的視圖,它是一個(gè)簡(jiǎn)單的python函數(shù)(或者一個(gè)基于類(lèi)的視圖)。視圖將獲得如下參數(shù):

一個(gè)HttpRequest 實(shí)例。

如果匹配的正則表達(dá)式返回來(lái)了沒(méi)有命名的組,那么正則表達(dá)式匹配的內(nèi)容將作為位置參數(shù)提供給視圖。

關(guān)鍵字參數(shù)由正則表達(dá)式匹配的命名組成,但是可以被django.conf.urls.url()的可選參數(shù)kwargs 覆蓋。

5 如果沒(méi)有匹配到正則表達(dá)式,或者如果過(guò)程中拋出一個(gè)異常,django將調(diào)用一個(gè)適當(dāng)?shù)腻e(cuò)誤處理試圖。

2 用戶(hù)請(qǐng)求數(shù)據(jù)處理過(guò)程

django 進(jìn)階之view layer

Middlewares: 過(guò)濾函數(shù),俗稱(chēng)過(guò)濾器,在執(zhí)行之前和執(zhí)行之后進(jìn)行某些操作

3 URL 命名空間

1 兩種命名空間

app namespace

instance namespace

2 app namespace

app/urls.py

app_name='app' # 此中方式和在demo/urls.py中的
url(r'^app/', include("app.urls",namespace="app")), 作用相同

命名空間的作用主要用作隔離


上述表示使用了此配置后,此配置文件中的所有數(shù)據(jù)都在此名稱(chēng)空間下,在使用url時(shí),需要在其上面加上名稱(chēng)空間的名稱(chēng)

django 進(jìn)階之view layer

3 instance namespace

instance 級(jí)別,名稱(chēng)不可以重復(fù)

在demo/urls.py中的

url(r'^app/', include("app.urls",namespace="app")), 用于在項(xiàng)目的urls.py中的include()中指定,作用和上面的相同,均可用于反向解析


說(shuō)明:

app namespace 使用場(chǎng)景: 通常使用此方式 ,除非有多個(gè)include則使用instance namespace

3 url 反向解析

1 解析概述

如果在你的代碼中,需要使用一些類(lèi)似url模板標(biāo)簽,Django提供了下列功能:

正解析: url ->view

反解析: view name -> url

2 reverse

此函數(shù)用于通過(guò)url中指定的name來(lái)返回對(duì)應(yīng)的url

格式如下

reverse(viewname,urlconf=None,args=None,Kwargs=None,current_app=None)
viewname 可以是一個(gè)url模式名稱(chēng)或一個(gè)可調(diào)用的視圖對(duì)象

django 進(jìn)階之view layer

3 reverse_lazy

懶加載下的 reverse

格式如下:
reverse_lazy(viewname, urlconf=None, args=None, kwargs=None, current_app=None)


作用:
提供反向URL作為url基于類(lèi)的通用視圖的屬性。
向裝飾器提供反向URL(例如裝飾器的login_url參數(shù)django.contrib.auth.decorators.permission_required() )。
提供反向URL作為函數(shù)簽名中參數(shù)的默認(rèn)值。


1 在模板中: 使用url 模板標(biāo)簽
2 在python 代碼中,使用django.core.urlresolvers.reverse() 函數(shù)
3 在更高層的與處理django模型實(shí)例相關(guān)的代碼中,使用get_absolute_url() 方法

4 多種URL

demo.urls.py 中配置如下

from django.conf.urls import url, include
from django.contrib import admin
from django.http import HttpResponse

def year(request):
    return HttpResponse("year")

def month(request):
    return HttpResponse("month")

def ymd(request):
    return HttpResponse("year-month-days")

urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^app/', include("app.urls")),
    url(r'^[0-9]{4}/$', year),
    url(r'^[0-9]{2}/$', month),
    url(r'^[0-9]{4}/[0-9]{2}/[0-9]{2}/$', ymd),
]

說(shuō)明:

1 若要從URL中捕獲一個(gè)值,只需要在它周?chē)胖靡粚?duì)圓括號(hào)

2 不需要添加一個(gè)前導(dǎo)的反斜杠,因?yàn)槊總€(gè)URL都有,

3 每個(gè)正則表達(dá)式前面的'r' 是可選的,建議加上,它告訴python這個(gè)字符串是原始的字符串,字符串中的任何意義都不應(yīng)該被轉(zhuǎn)義。

4 默認(rèn)捕捉到的都是字符串

5 上述的匹配方式因?yàn)榧由狭?,因此其是絕對(duì)匹配

5 URL 無(wú)法匹配的錯(cuò)誤處理

當(dāng)django找不到一個(gè)匹配請(qǐng)求的URL的正則表達(dá)式時(shí),或者當(dāng)拋出一個(gè)異常時(shí),django會(huì)將調(diào)用有個(gè)錯(cuò)誤處理視圖


默認(rèn)的錯(cuò)誤處理視圖

-handler404
-handler500
-handler403
-handler400

6 url 多種組合寫(xiě)法

1 引入配置

demo/urls.py 中如下

from django.conf.urls import url, include
from django.contrib import admin
from django.http import HttpResponse

def year(request):
    return HttpResponse("year")

def month(request):
    return HttpResponse("month")

def ymd(request):
    return HttpResponse("year-month-days")

extra_patters = [
    url(r'^[0-9]{4}/$', year),
    url(r'^[0-9]{2}/$', month),
    url(r'^[0-9]{4}/[0-9]{2}/[0-9]{2}/$', ymd),

]

urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^app/', include("app.urls"), name="app"),
    url(r'test/', include(extra_patters)),  # 引入上述配置的匹配規(guī)則
]

django 進(jìn)階之view layer

django 進(jìn)階之view layer

2 多層級(jí)配置

from django.conf.urls import url, include
from django.contrib import admin
from django.http import HttpResponse

def year(request):
    return HttpResponse("year")

def month(request):
    return HttpResponse("month")

def ymd(request):
    return HttpResponse("year-month-days")

urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^app/', include("app.urls"), name="app"),
    url(r'test/', include([

        url(r'^[0-9]{4}/$', year),
        url(r'^[0-9]{2}/$', month),
        url(r'^[0-9]{4}/[0-9]{2}/[0-9]{2}/$', ymd),

    ])),  # 引入上述配置的匹配規(guī)則
]

3 追加配置

from django.conf.urls import url, include
from django.contrib import admin
from django.http import HttpResponse

def year(request):
    return HttpResponse("year")

def month(request):
    return HttpResponse("month")

def ymd(request):
    return HttpResponse("year-month-days")

urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^app/', include("app.urls"), name="app"),
    url(r'test/', include([

        url(r'^[0-9]{4}/$', year),
        url(r'^[0-9]{2}/$', month),
        url(r'^[0-9]{4}/[0-9]{2}/[0-9]{2}/$', ymd),

    ])),  # 引入上述配置的匹配規(guī)則
]

def log(request):
    return HttpResponse("log")

urlpatterns += [
    url(r'log/', log)
]

結(jié)果如下

django 進(jìn)階之view layer

6 URL 參數(shù)的捕獲和繼承

demo/urls.py

from django.conf.urls import url, include
from django.contrib import admin
urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^(?P<question_id>[0-9]+)/app/', include("app.urls"), name="app"),  # 此處配置直接捕獲question_id 進(jìn)行處理
]

app/urls.py 中配置如下

from django.conf.urls import url, include
from . import views

app_name = "app"
urlpatterns = [
    url(r'^index/$', views.index, name="index"),
    url(r'^$', views.detal, name="detal"),
    url(r'^result$', views.result, name="result"),
    url(r'^vote$', views.vote, name="vote"),
]

去除了之前的(?P<question_id>[0-9]+)


app/view.py

修改 index接受參數(shù),需要添加接受此參數(shù),否則其無(wú)法訪問(wèn)

def index(request, question_id):
    lastes_question_list = models.Question.objects.order_by('-pub_date')[:5]
    context = {"lastes_question_list": lastes_question_list}
    return render(request, template_name="app/index.html", context=context)

django 進(jìn)階之view layer

傳遞額外參數(shù)

urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^(?P<question_id>[0-9]+)/app/', include("app.urls"), {"question_id": 1}),  # 此處配置直接捕獲question_id 進(jìn)行處理
]

說(shuō)明: 此處配置的必須是正則表達(dá)式中匹配的值,此處會(huì)覆蓋正則表達(dá)式中匹配的值,此處的question_id,為1

django 進(jìn)階之view layer

django 進(jìn)階之view layer

五 view 高級(jí)部分

1 發(fā)送郵件

1 setting.py 中配置如下

需要在項(xiàng)目project.setting.py 中配置相關(guān)參數(shù)
本項(xiàng)目是在 demo/setting.py 中配置

# 郵件發(fā)送相關(guān)配置
EMAIL_HOST = "smtp.163.com"  # 服務(wù)地址
EMAIL_PORT = 25  # 發(fā)送使用的端口
EMAIL_HOST_USER = ""  # 發(fā)送郵件使用的賬號(hào)
EMAIL_HOST_PASSWORD = ""  # 發(fā)送授權(quán)密碼
# EMAIL_USE_TLS=True  # 是否啟用TLS 
# EMAIL_USE_SSL=True  # 是否啟用SSL 

2 send_mail 格式含義如下

def send_mail(subject, message, from_email, recipient_list,
              fail_silently=False, auth_user=None, auth_password=None,
              connection=None, html_message=None):
            pass 

其中:
subject 表示郵件的標(biāo)題
message 表示郵件內(nèi)容
from_email 表示發(fā)件人
recipient_list 表示收件人列表

3 app/views.py 中代碼如下

from django.core.mail import send_mail

def sendemail(request):
    if request.method == "POST":
        subject = request.POST.get('subject', '')
        message = request.POST.get('message', '')
        recipient_list = request.POST.get('recipient_list', '')
        print(recipient_list)
        if subject and message and recipient_list:
            try:
                send_mail(subject, message=message, from_email='18829272841@163.com',
                          recipient_list=['zhangbing@zhishoubao.com'])
            except  Exception as e:
                return HttpResponse("Invalid header found.")
            return HttpResponseRedirect('/app/index')
        else:
            return HttpResponse("Make  sure all  fields  are entered  and valid.")
    return render(request, 'app/sendemail.html')

4 app/urls.py 中修改如下

from django.conf.urls import url, include
from . import views

app_name = "app"
urlpatterns = [
    url(r'^index/$', views.index, name="index"),
    url(r'^(?P<question_id>[0-9]+)$', views.detal, name="detal"),
    url(r'^(?P<question_id>[0-9]+)/result$', views.result, name="result"),
    url(r'^(?P<question_id>[0-9]+)/vote$', views.result, name="vote"),
    url(r'^sendemail/$', views.sendemail, name="sendemail"),

5 templates/app/sendemail.html中修改如下

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>郵件發(fā)送</title>
</head>
<body>
<form action="" method="post">
    <label> 主題 </label>
    <input type="text" name="subject">
    <br/>
    <label> 內(nèi)容 </label>
    <input type="text" name="message">
    <br/>
    <label> 發(fā)件人列表</label>
    <input type="email" name="recipient_list">
    <br/>
    <input type="submit" value="提交">
</form>
</body>
</html>

6 結(jié)果如下

django 進(jìn)階之view layer

7 跳轉(zhuǎn)到如下頁(yè)面

django 進(jìn)階之view layer

2 導(dǎo)出CSV 文件

1 app/views.py中配置如下

import csv
import datetime

def get_csv(request):
    if request.method == "POST":
        response = HttpResponse(content_type="text/csv")
        response['Content-Disposition'] = 'attachment;filename={}.csv'.format(
            datetime.datetime.now().strftime("%Y-%m-%d"))
        writer = csv.writer(response)
        writer.writerow(["第一行", 1, 2, 3, 4])
        writer.writerow(["第二行", 'A', 'B', 'C', 'D'])
        return response
    return render(request, 'app/get_csv.html')

2 app/urls.py 中配置如下

from django.conf.urls import url, include
from . import views

app_name = "app"
urlpatterns = [
    url(r'^index/$', views.index, name="index"),
    url(r'^(?P<question_id>[0-9]+)$', views.detal, name="detal"),
    url(r'^(?P<question_id>[0-9]+)/result$', views.result, name="result"),
    url(r'^(?P<question_id>[0-9]+)/vote$', views.result, name="vote"),
    url(r'^sendemail/$', views.sendemail, name="sendemail"),
    url(r'^get_csv/$', views.get_csv, name="getcsv"),

]

3 templates/app/get_csv.html中配置如下

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>觸發(fā)獲取get_csv</title>
</head>
<body>
<form action="" method="post">
    <input type="submit" value="獲取csv">
</form>
</body>
</html>

4 結(jié)果如下

django 進(jìn)階之view layer

3 上傳文件

1 app/views.py 中配置如下

def upload_file(request):
    if request.method == "POST":
        print(request.FILES)
        upload_file = request.FILES.get('file', None)
        if upload_file is None:
            return HttpResponse("Not file get")
        else:
            with  open('/tmp/{}'.format(upload_file.name), 'wb')  as  f:
                f.write(upload_file.read())
            return HttpResponse("{} 文件上傳成功,大小為:{}".format(upload_file.name, upload_file.size))
    else:
        return render(request, 'app/upload_file.html')

2 app/urls.py 中配置如下

from django.conf.urls import url, include
from . import views

app_name = "app"
urlpatterns = [
    url(r'^index/$', views.index, name="index"),
    url(r'^(?P<question_id>[0-9]+)$', views.detal, name="detal"),
    url(r'^(?P<question_id>[0-9]+)/result$', views.result, name="result"),
    url(r'^(?P<question_id>[0-9]+)/vote$', views.result, name="vote"),
    url(r'^sendemail/$', views.sendemail, name="sendemail"),
    url(r'^get_csv/$', views.get_csv, name="getcsv"),
    url(r'^upload_file/$', views.upload_file, name="upload_file"),

]

3 templates/app/upload_file.html中配置如下

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>上傳文件</title>
</head>
<body>
<form action="" method="post" ENCTYPE="multipart/form-data">
    <input type="file" name="file">
    <br/>
    <input type="submit" value="上傳文件">
</form>
</body>
</html>

4 結(jié)果如下

django 進(jìn)階之view layer

5 說(shuō)明

-request.FILES

  • enctype 默認(rèn)是 "application/x-www-form-urlencoded",上傳文件時(shí)需要修改為"multipart/form-data"

4 下載文件

1 app.views.py 中配置如下

def download_file(request):
    if request.method == "POST":
        f = open('/tmp/2020-01-03.csv', 'rb')
        response = HttpResponse(f, content_type="application/csv")
        response['Content-Disposition'] = 'attachment;filename={}.csv'.format(
            datetime.datetime.now().strftime("%Y-%m-%d"))
        f.close()
        return response
    else:
        return render(request, 'app/download_file.html')

2 app/urls.py中配置

from django.conf.urls import url, include
from . import views

app_name = "app"
urlpatterns = [
    url(r'^index/$', views.index, name="index"),
    url(r'^(?P<question_id>[0-9]+)$', views.detal, name="detal"),
    url(r'^(?P<question_id>[0-9]+)/result$', views.result, name="result"),
    url(r'^(?P<question_id>[0-9]+)/vote$', views.result, name="vote"),
    url(r'^sendemail/$', views.sendemail, name="sendemail"),
    url(r'^get_csv/$', views.get_csv, name="getcsv"),
    url(r'^upload_file/$', views.upload_file, name="upload_file"),
    url(r'^download_file/$', views.download_file, name="download_file"),

]

3 templates/app/download_file.html中配置如下

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>下載數(shù)據(jù)</title>
</head>
<body>
<form action="" method="post">
    <input type="submit" value="下載文件">
</form>
</body>
</html>

django 進(jìn)階之view layer

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI