1. 程式人生 > 實用技巧 >django 上下文管理器、帶引數的url、多表操作、中介軟體、url中引數獲取方法

django 上下文管理器、帶引數的url、多表操作、中介軟體、url中引數獲取方法

1.上下文管理器

#views.py
from django.http import HttpResponseRedirect
from django.shortcuts import render,HttpResponse
from . import models

# Create your views here.

def category(request,id):
    category_obj = models.Category.objects.get(id=id)
    articles = models.Article.objects.filter(category_id=category_obj)
    
return render(request, 'category.html', { 'articles': articles,'category_obj':category_obj})
#建立上下文管理器:content_process.py (位置:sky/user/content_process.py)
#上下文管理器:使用者訪問url先呼叫views中的方法,方法跳轉到對應的頁面,頁面再呼叫上下文管理器,所有跳轉頁面都會去
#呼叫上下文管理器,都會獲取上下文管理器中返回的值,可以使用也可以不使用,也可以在上下文管理器中加個判斷,哪些頁面訪問採返回值
from . import models
def process_category(request): categories = models.Category.objects.all() return {'categories':categories}
#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', 'user.content_process.process_category' ], }, }, ]
#category.html 
  <!--文章分類-->
                <div class="card border-0 rounded-0 px-3 mb-2 mb-md-3" id="category-card">
                    <div class="card-header bg-white px-0">
                        <strong><i class="fa fa-book mr-2 f-17"></i>文章分類</strong>
                    </div>

                    <ul class="list-group list-group-flush f-16">

                        {% for category in categories %}

                        <li class="list-group-item d-flex justify-content-between align-items-center pr-2 py-2">
                            <a class="category-item" href="/category/{{ category.id }}"
                               title="檢視【{{ category.name }}】分類下所有文章">{{ category.name }}</a>
                            <span class="badge text-center" title="當前分類下有{{ category.article_set.count }}篇文章">{{ category.article_set.count }}</span>
                        </li>
                        {% endfor %}
                    </ul>
                </div>
             

2.帶引數的url、多表操作

#views.py
from django.http import HttpResponseRedirect
from django.shortcuts import render,HttpResponse
from . import models

# Create your views here.

def category(request,id):
    category_obj = models.Category.objects.get(id=id)
    articles = models.Article.objects.filter(category_id=category_obj)
#urls.py
from django.contrib import admin
from django.urls import path
from user import views

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', views.index),
    path('category/<int:id>', views.category)
]
#category.html  通過分類表調文章表,獲取某個分類下對應文章總數
 <!--文章分類-->
                <div class="card border-0 rounded-0 px-3 mb-2 mb-md-3" id="category-card">
                    <div class="card-header bg-white px-0">
                        <strong><i class="fa fa-book mr-2 f-17"></i>文章分類</strong>
                    </div>

                    <ul class="list-group list-group-flush f-16">

                        {% for category in categories %}

                        <li class="list-group-item d-flex justify-content-between align-items-center pr-2 py-2">
                            <a class="category-item" href="/category/{{ category.id }}"
                               title="檢視【{{ category.name }}】分類下所有文章">{{ category.name }}</a>
                            <span class="badge text-center" title="當前分類下有{{ category.article_set.count }}篇文章">{{ category.article_set.count }}</span>
                        </li>
                        {% endfor %}
                    </ul>
                </div>

3.中介軟體、url中引數獲取方法

#構建庫:models.py
from django.db import models
class Interface(models.Model):
    name = models.CharField(verbose_name='介面名稱',max_length=50)
    path = models.CharField(verbose_name='介面路徑',max_length=60,unique=True)
    response = models.TextField(verbose_name='返回資料')

    class Meta:
        db_table = 'interface'
        verbose_name = '介面'
        verbose_name_plural = verbose_name

    def __str__(self):
        return self.name
#建立post.html頁面
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<form action="/post" method="post">
{% csrf_token %}

    <h1>寫文章的</h1>
    <div>
            title:<input type="text" name="title">

    </div>
    <div>
            content:<input type="text" name="content">

    </div>

    <div>
        <select name="category">
            {% for category in categories %}
            <option value="{{ category.id }}">{{ category.name }}</option>
            {% endfor %}
        </select>
    </div>

    <div>
            <input type="submit" value="提交">

    </div>

</form>


</body>
</html>

#views.py

def article(request):
   #url中引數獲取方法:
# print(request.method) # 請求方式 # print(request.GET) # url?key=vlauye # print(request.POST) # url key-vlaue # print(request.COOKIES) # print(request.path_info) # 請求的路徑 /post /cate # print(request.FILES) # 獲取檔案 # print(request.META) # 請求頭相關的都在這裡 # print(request.body) # body裡面的內容 if request.method=='GET': return render(request,'post.html') else: title = request.POST.get('title') content = request.POST.get('content') category = request.POST.get('category') models.Article.objects.create(title=title,content=content,category_id=category) return HttpResponseRedirect('/')

# 配置urls.py(位置:sky/sky/urls.py)
from django.contrib import admin
from django.urls import path
from user import views

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', views.index),
    path('category/<int:id>', views.category),
    path('post', views.article)
] 

#建立中介軟體middle_wares.py(位置:sky/user/middle_wares.py)
from django.http import HttpResponse
from django.middleware.common import MiddlewareMixin
from . import models
class TestMiddleWare(MiddlewareMixin):

    def process_request(self,request):
        '''請求過來之後先走到的這裡'''
     #這裡模擬的是根據請求介面獲取對應的響應
        path = request.path_info
        interface = models.Interface.objects.filter(path = path).first()
        if interface:
            return HttpResponse(interface.response)


    def process_response(self,request,response):
        #攔截返回的,最終響應的資訊會走到這裡
        print('response....')
        return response

    # def process_exception(self,request,exception):
    #     #攔截異常的,請求中有異常會走到這裡
    #     print('出異常了。。')
    #     return HttpResponse('hhhh')
#配置settings.py
MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
    'user.middle_wares.TestMiddleWare'
]