青少年编程与数学 02-009 Django 5 Web 编程 09课题、视图函数
- 一、视图
- 视图的类型
- 函数视图
- 类视图
- 视图的组成
- 视图的配置
- 视图的高级特性
- 二、控制器?
- 三、函数视图
- 基本结构
- 请求处理
- 数据获取和处理
- 模板渲染
- 视图装饰器
- 错误处理
- 四、路由配置
- 1. 创建函数视图
- 2. 导入视图函数
- 3. 定义URL模式
- 4. 包含应用的URL配置
- 5. 访问URL
- 动态URL参数
- 五、视图参数
- 1. 从URL中捕获动态参数
- 定义URL模式
- 视图函数接收参数
- 2. 从请求中获取参数
- 获取查询参数(GET请求)
- 获取表单数据(POST请求)
- 注意事项
- 六、练习
- 步骤 1: 创建项目和应用
- 步骤 2: 定义模型
- 步骤 3: 迁移模型
- 步骤 4: 创建视图
- 步骤 5: 配置URL
- 步骤 6: 创建模板
- 步骤 7: 运行开发服务器
- 步骤 8: 访问应用
- 注意事项
课题摘要: 本文深入探讨了Django中的视图函数,包括函数视图和类视图的定义与使用。函数视图通过简单函数处理请求并返回响应,而类视图以类形式定义,可处理多种HTTP请求方法。文章详细介绍了视图的组成,如请求处理逻辑、数据获取与处理、模板渲染及响应生成,并解释了如何通过URL配置文件将视图与URL路径关联。此外,还介绍了视图的高级特性,如通用视图、视图混入类和视图装饰器,以及如何处理动态URL参数和请求参数。最后,通过一个完整的示例项目,展示了如何创建和配置视图,实现书籍信息的展示和管理。
一、视图
在Django中,视图(View)是处理用户请求并返回响应的函数或类。视图是Django MVC(模型-视图-控制器)架构中的“视图”部分,负责业务逻辑的处理和数据的呈现。以下是关于Django视图的详细介绍:
视图的类型
Django支持两种主要类型的视图:函数视图和类视图。
函数视图
函数视图是一个简单的Python函数,它接受一个HttpRequest
对象作为参数,并返回一个HttpResponse
对象或抛出一个异常。函数视图适用于简单的请求处理逻辑。
python"># myapp/views.py
from django.http import HttpResponsedef my_view(request):# 处理请求的业务逻辑# ...return HttpResponse("Hello, World!")
在函数视图中,你可以访问request
对象的属性和方法来获取请求信息,如请求方法(GET或POST)、请求参数、用户信息等。然后,你可以根据业务逻辑生成响应内容,并通过返回HttpResponse
对象将其发送给客户端.
类视图
类视图是一个继承自django.views.View
或其子类的Python类。它通过定义方法来处理不同类型的HTTP请求,如get()
、post()
、put()
等。类视图适用于需要共享代码或具有复杂行为的视图。
python"># myapp/views.py
from django.http import HttpResponse
from django.views import Viewclass MyView(View):def get(self, request):# 处理GET请求的业务逻辑# ...return HttpResponse("GET request received.")def post(self, request):# 处理POST请求的业务逻辑# ...return HttpResponse("POST request received.")
在类视图中,每个HTTP请求方法对应一个类方法。当请求到达时,Django会根据请求方法调用相应的类方法来处理请求。你可以在类视图中定义共享的属性和方法,以便在不同的请求处理方法之间重用代码.
视图的组成
一个典型的Django视图通常包含以下几个部分:
- 请求处理逻辑:根据请求的类型和内容,执行相应的业务逻辑。例如,查询数据库、处理表单数据、调用外部服务等.
- 数据获取和处理:从模型或其他数据源获取所需的数据,并进行必要的处理和转换,以便将其呈现给用户.
- 模板渲染:使用模板引擎将处理后的数据渲染成HTML或其他格式的响应内容。模板可以包含HTML代码和模板标签,用于动态生成页面内容.
- 响应生成:根据处理结果和渲染的内容,创建并返回一个
HttpResponse
对象或其他类型的响应对象,如JsonResponse
、FileResponse
等.
视图的配置
要将视图与URL路径关联起来,需要在Django项目的URL配置文件(通常是urls.py
)中定义URL模式,并将其映射到相应的视图函数或类视图。
python"># myapp/urls.py
from django.urls import path
from . import viewsurlpatterns = [path('my-view/', views.my_view, name='my-view'),path('my-class-view/', views.MyView.as_view(), name='my-class-view'),
]
在这个例子中,path()
函数用于定义URL模式。对于函数视图,直接将视图函数作为第二个参数传递;对于类视图,使用as_view()
方法将类视图转换为可调用的视图函数.
视图的高级特性
Django提供了许多高级视图类和混入类,可以帮助你快速实现常见的Web功能,如表单处理、分页、权限控制等。
- 通用视图:Django内置了一些通用视图类,如
ListView
、DetailView
、CreateView
、UpdateView
、DeleteView
等,它们提供了处理常见CRUD操作的基本逻辑,你可以通过继承和配置这些通用视图来简化视图的编写. - 视图混入类:混入类是一些包含特定功能的类,你可以将它们与视图类组合使用,以实现特定的行为。例如,
LoginRequiredMixin
用于要求用户登录才能访问视图,PermissionRequiredMixin
用于检查用户权限等. - 视图装饰器:Django提供了一些视图装饰器,如
login_required
、permission_required
等,可以用于函数视图或类视图的方法,以实现请求的预处理和权限控制等功能.
通过合理地使用Django的视图功能,你可以灵活地处理用户的请求,实现复杂的业务逻辑,并生成各种类型的响应内容,满足Web应用的需求.
二、控制器?
在Django的架构中,视图(View)实际上承担了传统MVC(模型-视图-控制器)架构中“控制器”(Controller)的角色。Django的架构有时被称为“MTV”(模型-模板-视图),其中:
- 模型(Model):负责数据存储和业务逻辑。
- 模板(Template):负责呈现数据,即生成HTML等格式的用户界面。
- 视图(View):负责处理用户请求,调用模型获取数据,并选择合适的模板进行渲染,然后返回响应给用户。
在传统的MVC架构中,控制器(Controller)是处理用户输入并调用模型和视图来生成响应的部分。在Django中,视图(View)正是承担了这个角色:
- 处理请求:视图接收用户的HTTP请求,并根据请求的内容(如URL、方法、参数等)来决定如何处理.
- 调用模型:视图可以调用模型来获取、创建、更新或删除数据.
- 选择模板:视图根据处理结果选择合适的模板,并将数据传递给模板进行渲染.
- 返回响应:视图将渲染后的结果封装成一个HTTP响应对象,并返回给用户.
因此,虽然在Django中称为“视图”,但从功能上看,它更接近于传统MVC架构中的“控制器”。这种命名上的差异主要是为了更好地反映Django的设计哲学和实现方式,即视图主要关注于处理请求和生成响应,而模板则专注于数据的呈现.
三、函数视图
函数视图是Django中实现视图逻辑的一种方式,它通过定义一个简单的Python函数来处理HTTP请求并返回响应。函数视图适用于处理简单的请求逻辑,易于理解和实现。以下是函数视图的详细介绍:
基本结构
一个函数视图的基本结构如下:
python">from django.http import HttpResponsedef my_view(request):# 处理请求的业务逻辑# ...return HttpResponse("Hello, World!")
- 导入HttpResponse:从
django.http
模块导入HttpResponse
类,用于创建HTTP响应对象. - 定义视图函数:定义一个函数,通常命名为
my_view
或其他有意义的名称。该函数接受一个参数request
,表示当前的HTTP请求对象. - 处理请求:在函数体内编写处理请求的业务逻辑。你可以访问
request
对象的属性和方法来获取请求信息,如请求方法(request.method
)、请求参数(request.GET
或request.POST
)、用户信息(request.user
)等. - 返回响应:根据处理结果创建并返回一个
HttpResponse
对象或其他类型的响应对象,如JsonResponse
、FileResponse
等,将响应内容发送给客户端.
请求处理
在函数视图中,你可以根据请求的方法和参数来执行不同的操作。例如,处理GET和POST请求:
python">from django.http import HttpResponsedef my_view(request):if request.method == 'GET':# 处理GET请求return HttpResponse("GET request received.")elif request.method == 'POST':# 处理POST请求return HttpResponse("POST request received.")else:# 处理其他请求方法return HttpResponse("Unsupported request method.", status=405)
- 判断请求方法:通过
request.method
属性获取请求的方法(如'GET'
、'POST'
等),并根据方法执行相应的处理逻辑. - 处理GET请求:通常用于获取数据或渲染页面,可以访问
request.GET
字典来获取URL中的查询参数. - 处理POST请求:通常用于提交表单数据或执行某些操作,可以访问
request.POST
字典来获取表单提交的数据. - 返回状态码:在返回响应时,可以通过
HttpResponse
的status
参数指定HTTP状态码,如405
表示方法不允许.
数据获取和处理
函数视图可以从模型中获取数据,并进行必要的处理:
python">from django.http import HttpResponse
from .models import Bookdef book_list(request):# 从模型中获取数据books = Book.objects.all()# 处理数据book_titles = [book.title for book in books]# 返回响应return HttpResponse("<br>".join(book_titles))
- 查询模型数据:使用模型的
objects
管理器(如Book.objects.all()
)来查询数据库中的数据. - 处理数据:对查询结果进行处理,例如提取书籍的标题并存储在列表中.
- 返回响应:将处理后的数据转换为字符串或其他格式,并通过
HttpResponse
返回给客户端.
模板渲染
在函数视图中,你可以使用Django的模板引擎来渲染数据并生成HTML响应:
python">from django.shortcuts import render
from .models import Bookdef book_list(request):# 从模型中获取数据books = Book.objects.all()# 渲染模板return render(request, 'book_list.html', {'books': books})
- 导入render函数:从
django.shortcuts
模块导入render
函数,用于渲染模板. - 调用render函数:传递
request
对象、模板名称(如'book_list.html'
)和一个包含上下文数据的字典(如{'books': books}
)给render
函数. - 模板文件:在模板文件中,你可以使用模板标签和过滤器来动态生成HTML内容,例如遍历
books
列表并显示每本书的信息.
视图装饰器
Django提供了多种视图装饰器,可以用于函数视图以实现特定的功能,如权限控制、缓存等:
python">from django.contrib.auth.decorators import login_required
from django.http import HttpResponse@login_required
def my_protected_view(request):# 只有登录用户才能访问此视图return HttpResponse("Welcome, logged-in user!")
- 导入装饰器:从
django.contrib.auth.decorators
模块导入login_required
装饰器. - 应用装饰器:在函数视图定义前使用
@login_required
装饰器,表示只有登录用户才能访问该视图. - 访问控制:当未登录用户尝试访问该视图时,会被重定向到登录页面或返回一个错误响应.
错误处理
在函数视图中,你可以捕获和处理可能出现的错误,以提供更友好的用户体验:
python">from django.http import HttpResponse
from django.shortcuts import get_object_or_404
from .models import Bookdef book_detail(request, book_id):try:# 尝试获取书籍对象book = Book.objects.get(id=book_id)except Book.DoesNotExist:# 如果书籍不存在,返回404错误return HttpResponse("Book not found.", status=404)# 返回书籍详情响应return HttpResponse(f"Book: {book.title}")# 或者使用get_object_or_404函数简化
def book_detail(request, book_id):book = get_object_or_404(Book, id=book_id)return HttpResponse(f"Book: {book.title}")
- 捕获异常:在获取书籍对象时,捕获
Book.DoesNotExist
异常,表示书籍不存在. - 返回404错误:使用
HttpResponse
的status
参数返回404状态码,表示请求的资源未找到. - 使用get_object_or_404:Django提供了
get_object_or_404
函数,它会自动捕获DoesNotExist
异常并返回404错误,简化了错误处理的代码.
函数视图是Django中实现视图逻辑的基础方式之一,它简单、直观且功能强大,适用于处理各种HTTP请求并生成相应的响应内容。通过合理地编写函数视图,你可以实现复杂的业务逻辑,并为用户提供丰富的Web应用功能.
四、路由配置
在Django中,要将函数视图与特定的URL路径关联起来,需要在应用的URL配置文件(通常是urls.py
)中进行路由配置。以下是函数视图路由配置的详细步骤:
1. 创建函数视图
首先,在应用的views.py
文件中定义一个函数视图。例如:
python"># myapp/views.py
from django.http import HttpResponsedef my_view(request):return HttpResponse("Hello, World!")
2. 导入视图函数
在应用的urls.py
文件中,导入刚刚定义的视图函数。例如:
python"># myapp/urls.py
from django.urls import path
from . import views
这里使用from . import views
从当前应用的views.py
文件中导入所有的视图函数。你也可以单独导入特定的视图函数,例如from .views import my_view
。
3. 定义URL模式
在urls.py
文件中,使用path()
函数定义URL模式,并将URL路径映射到相应的视图函数。例如:
python"># myapp/urls.py
from django.urls import path
from . import viewsurlpatterns = [path('hello/', views.my_view, name='hello'),
]
path()
函数:用于定义一个URL模式。它接受两个主要参数:URL路径和视图函数.- URL路径:指定URL的路径部分,例如
'hello/'
。路径可以包含路径转换器,用于捕获动态参数. - 视图函数:指定处理该URL路径的视图函数,例如
views.my_view
。 name
参数:为URL模式指定一个名称,方便在模板和视图中通过名称引用该URL。例如,name='hello'
。
4. 包含应用的URL配置
如果你的项目中有多个应用,通常会在项目的主urls.py
文件中包含每个应用的URL配置。例如:
python"># project/urls.py
from django.contrib import admin
from django.urls import include, pathurlpatterns = [path('admin/', admin.site.urls),path('myapp/', include('myapp.urls')),
]
这里使用include()
函数将myapp
应用的URL配置包含到项目的主URL配置中。path('myapp/', include('myapp.urls'))
表示将所有以'myapp/'
开头的URL路径委托给myapp
应用的urls.py
文件来处理.
5. 访问URL
启动Django开发服务器后,你可以通过浏览器访问配置好的URL路径。例如,访问http://127.0.0.1:8000/myapp/hello/
将会触发my_view
函数视图,并显示“Hello, World!”的响应内容.
动态URL参数
如果需要捕获动态参数,可以在URL路径中使用路径转换器。例如:
python"># myapp/urls.py
from django.urls import path
from . import viewsurlpatterns = [path('book/<int:book_id>/', views.book_detail, name='book_detail'),
]
- 路径转换器:
<int:book_id>
表示捕获一个整数类型的参数,并将其传递给视图函数。int
是路径转换器的类型,book_id
是参数的名称. - 视图函数参数:在视图函数中,你需要添加相应的参数来接收动态参数的值。例如:
python"># myapp/views.py
def book_detail(request, book_id):# 使用book_id进行数据库查询或其他操作return HttpResponse(f"Book ID: {book_id}")
通过以上步骤,你可以将函数视图与URL路径关联起来,实现请求的路由配置。Django的URL配置系统非常灵活,可以轻松地处理各种复杂的URL模式和动态参数.
五、视图参数
在Django中,为函数视图添加参数通常涉及两种情况:从URL中捕获动态参数和从请求中获取参数(如查询参数或表单数据)。以下是详细说明:
1. 从URL中捕获动态参数
你可以通过在URL模式中使用路径转换器来捕获动态参数,并将这些参数传递给视图函数。路径转换器允许你从URL中提取特定类型的数据,并将其作为参数传递给视图函数。
定义URL模式
在urls.py
文件中,使用路径转换器定义URL模式。常见的路径转换器类型包括int
、str
、slug
、uuid
等。
python"># myapp/urls.py
from django.urls import path
from . import viewsurlpatterns = [path('book/<int:book_id>/', views.book_detail, name='book_detail'),
]
在这个例子中,<int:book_id>
是一个路径转换器,它捕获URL中的整数部分,并将其作为book_id
参数传递给book_detail
视图函数.
视图函数接收参数
在视图函数中,添加相应的参数来接收从URL中捕获的动态参数。
python"># myapp/views.py
from django.http import HttpResponse
from .models import Bookdef book_detail(request, book_id):# 使用book_id进行数据库查询或其他操作book = Book.objects.get(id=book_id)return HttpResponse(f"Book: {book.title}")
在这个例子中,book_detail
视图函数接收一个名为book_id
的参数,你可以使用这个参数来查询数据库中的书籍记录或其他相关操作.
2. 从请求中获取参数
除了从URL中捕获参数外,你还可以从请求中获取参数,如查询参数(GET请求)或表单数据(POST请求).
获取查询参数(GET请求)
在GET请求中,查询参数通常附加在URL的查询字符串中。你可以通过request.GET
字典来获取这些参数。
python"># myapp/views.py
from django.http import HttpResponsedef search_books(request):query = request.GET.get('query', '')# 使用query进行数据库查询或其他操作return HttpResponse(f"Search query: {query}")
在这个例子中,search_books
视图函数通过request.GET.get('query', '')
获取名为query
的查询参数。如果参数不存在,则返回默认值''
(空字符串).
获取表单数据(POST请求)
在POST请求中,表单数据通常包含在请求体中。你可以通过request.POST
字典来获取这些数据。
python"># myapp/view.py
from django.http import HttpResponsedef create_book(request):if request.method == 'POST':title = request.POST.get('title', '')author = request.POST.get('author', '')# 使用title和author创建书籍记录# ...return HttpResponse("Book created successfully.")else:return HttpResponse("Invalid request method.", status=405)
在这个例子中,create_book
视图函数通过request.POST.get('title', '')
和request.POST.get('author', '')
获取表单提交的title
和author
数据。如果请求方法不是POST,则返回405状态码表示方法不允许.
注意事项
- 在定义URL模式时,确保路径转换器的名称与视图函数中的参数名称一致,以便正确地传递参数.
- 对于从请求中获取的参数,要进行适当的验证和清理,以确保参数的有效性和安全性,防止潜在的安全问题,如SQL注入等.
- 在处理表单数据时,通常建议使用Django的表单类(如
forms.Form
或forms.ModelForm
)来处理数据验证和清洗,这样可以更方便地管理表单数据并提高代码的可维护性.
六、练习
以下是一个完整的Django项目示例,展示了一个简单的应用视图的创建和配置过程。这个示例项目包含一个名为bookstore
的应用,用于展示和管理书籍信息。项目结构如下:
myproject/manage.pymyproject/__init__.pysettings.pyurls.pywsgi.pybookstore/__init__.pyadmin.pyapps.pymodels.pytests.pyurls.pyviews.py
步骤 1: 创建项目和应用
首先,创建一个新的Django项目和一个名为bookstore
的应用:
django-admin startproject myproject
cd myproject
python manage.py startapp bookstore
步骤 2: 定义模型
在bookstore/models.py
文件中定义一个Book
模型:
python"># bookstore/models.py
from django.db import modelsclass Book(models.Model):title = models.CharField(max_length=200)author = models.CharField(max_length=100)publication_year = models.IntegerField()is_available = models.BooleanField(default=True)def __str__(self):return self.title
步骤 3: 迁移模型
运行以下命令生成并应用数据库迁移:
python manage.py makemigrations
python manage.py migrate
步骤 4: 创建视图
在bookstore/views.py
文件中创建视图函数:
python"># bookstore/views.py
from django.shortcuts import render, get_object_or_404
from .models import Bookdef book_list(request):books = Book.objects.all()return render(request, 'book_list.html', {'books': books})def book_detail(request, book_id):book = get_object_or_404(Book, id=book_id)return render(request, 'book_detail.html', {'book': book})
步骤 5: 配置URL
在bookstore/urls.py
文件中配置URL模式:
python"># bookstore/urls.py
from django.urls import path
from . import viewsurlpatterns = [path('', views.book_list, name='book_list'),path('book/<int:book_id>/', views.book_detail, name='book_detail'),
]
然后,在项目的主urls.py
文件中包含bookstore
应用的URL配置:
python"># myproject/urls.py
from django.contrib import admin
from django.urls import include, pathurlpatterns = [path('admin/', admin.site.urls),path('bookstore/', include('bookstore.urls')),
]
步骤 6: 创建模板
在bookstore
应用目录下创建一个templates
文件夹,并在其中创建HTML模板文件:
-
book_list.html
:<!-- bookstore/templates/book_list.html --> <!DOCTYPE html> <html> <head><title>Book List</title> </head> <body><h1>Book List</h1><ul>{% for book in books %}<li><a href="{% url 'book_detail' book.id %}">{{ book.title }}</a> by {{ book.author }}</li>{% endfor %}</ul> </body> </html>
-
book_detail.html
:<!-- bookstore/templates/book_detail.html --> <!DOCTYPE html> <html> <head><title>{{ book.title }}</title> </head> <body><h1>{{ book.title }}</h1><p>Author: {{ book.author }}</p><p>Publication Year: {{ book.publication_year }}</p><p>Available: {{ book.is_available }}</p><a href="{% url 'book_list' %}">Back to Book List</a> </body> </html>
步骤 7: 运行开发服务器
启动Django开发服务器:
python manage.py runserver
步骤 8: 访问应用
在浏览器中访问以下URL:
- 书籍列表页面:
http://127.0.0.1:8000/bookstore/
- 书籍详情页面:
http://127.0.0.1:8000/bookstore/book/1/
(假设数据库中有一本书的ID为1)
注意事项
- 在实际开发过程中,你可能还需要为
Book
模型创建表单以便用户添加和编辑书籍信息,以及为bookstore
应用创建管理员界面等. - 为了使模板正常工作,确保在
myproject/settings.py
文件中正确配置了TEMPLATES
设置,特别是DIRS
选项,以便Django能够找到模板文件. - 本示例假设你已经安装了Django并熟悉基本的Django项目结构和配置。如果你是Django新手,建议先阅读Django的官方文档和教程,以更好地理解Django的工作原理和最佳实践.