Django 是最流行的 Python Web 框架,用于快速 Web 应用程序开发。它提供了一个内置界面,可以轻松使用它。它也被称为包含电池的框架,因为它为每个操作提供内置设施。

我们大多数人可能已经熟悉基于函数的视图,并且知道如何使用基于函数的视图处理请求。

在本教程中,我们将介绍基于类的通用视图。这些是一组高级内置视图,用于实现选择性 CRUD(创建、检索、更新和删除)操作。使用基于类的视图,我们可以轻松处理视图的 GET、POST 请求。

它们并不能替代基于函数的视图,而是在基于函数的视图之上提供一些额外的功能。

让我们简要概述一下基于函数的视图和基于类的视图。

基于函数的视图

基于函数的视图适合初学者;初学者很容易理解它们。与基于类的视图相比,它很容易理解。

  • 它易于理解且易于使用。
  • 它提供了显式的代码流程。
  • 直接使用装饰器。

但基于函数的视图无法扩展,并且还会导致代码冗余。

基于类的视图

基于类的视图可以用来代替基于函数的视图。所有操作都使用 Python 对象而不是函数进行处理。它们提供了一些关于基于函数的视图的优秀示例。基于类的视图可以轻松地实现CRUD操作。

  • 它遵循 Django 的 DRY 约定。
  • 我们可以使用 Mixin 扩展基于类的视图,并根据需求添加更多功能。
  • 它允许继承另一个类,可以针对各种用例进行修改。

但这些内容理解起来很复杂,也很难阅读。它具有隐式代码流。

使用基于类的视图执行 CRUD(创建、检索、更新、删除)

我们将演示如何使用基于类的视图创建基本的 CRUD 应用程序。

我们将创建名为Hello 的项目,其中包含一个名为exampleapp 的应用程序。

在应用程序中,我们将在model.py文件中创建一个 Employee 模型。

例子 -

from django.db import models  
  
# Create your models here.  
  
class Employee(models.Model):  
    first_name = models.CharField(max_length=30)  
    last_name = models.CharField(max_length=30)  
    mobile = models.CharField(max_length=10)  
    email = models.EmailField()  
  
    def __str__(self):  
        return "%s %s" % (self.first_name, self.last_name)  

然后我们运行以下命令。

python manage.py makemigrations
python manage.py migrate

现在,我们将在 form.py 文件中为此模型创建 Django ModelForm 。它将用于向模板显示表单。

*froms.py*

from django.forms import fields  
from .models import Employee  
from django import forms  
  
class EmployeeForm(forms.ModelForm):  
  
    class Meta:  
        # To specify the model to be used to create form  
        model = Employee  
        # It includes all the fields of model  
        fields = '__all__'  

实现基于类的视图

基于函数的视图通过不同的类实例方法返回不同的 HTTP 请求方法。所以基于函数的将如下所示。

from django.http import HttpResponse  
def function_view(request):  
    if request.method == 'GET':  
        # View logic will place here  
        return HttpResponse('response')  

如果我们实现基于类的视图,它将如下所示。

from django.http import HttpResponse  
from django.views import View  
class NewView(View):  
    def get(self, request):  
        # View logic will place here  
        return HttpResponse('response')  

要处理基于类的视图,我们需要使用urls.py 文件中的as_view() 。

# urls.py  
from django.urls import path  
from myapp.views import NewView  
  
urlpatterns = [  
    path('about/', NewView.as_view()),  
]  

创建视图

CreateView 实现视图以在数据库中创建表的实例。该视图自动执行创建实例的所有操作。我们只需要指定模型名称即可创建视图及其字段。基于类的创建视图将搜索employee_form.html。让我们看看下面创建视图的示例。

注意 - employee_form.html 文件应包含在 template/app_name/employee_form.html 中。在我们的示例中,文件位置是 template/sampleapp/employee_form.html。

View.py

from .models import Employee  
from .forms import EmployeeForm  
from django.views.generic.edit import CreateView  
  
class EmployeeCreate(CreateView):  
    model = Employee  
  
    fields = '__all__'  

urls.py

from django.urls import path  
from .views import EmployeeCreate  
  
urlpatterns = [  
    path('', EmployeeCreate.as_view(), name = 'EmployeeCreate')  
]  

现在我们在本地主机上运行服务器。

输出:

1.png

在这里,我们得到了可以创建员工的表单。我们来看看创建员工的演示。

2.png

正如我们在管理面板中看到的,该员工已在数据库中创建。

3.png

检索视图

有两种检索视图 - ListViewDetailView。我们将使用 ListView,它指的是显示数据库中表的多个实例的视图。我们只需要指定应用ListView的模型名称,基于类的ListView将自动为我们完成这项工作。要检索数据,我们需要创建app_name/modelname_list.html文件。

views.py

from django.views.generic.list import ListView  
  
class EmployeeRetrieve(ListView):  
    model = Employee  

url.py

from django.urls import path  
from .views import EmployeeCreate, EmployeeRetrieve  
  
urlpatterns = [  
    path('', EmployeeCreate.as_view(), name = 'EmployeeCreate'),  
    path('retrieve/', EmployeeRetrieve.as_view(), name = 'EmployeeRetrieve')  
]  

示例应用程序/模板/employee_list.html

{% extends 'base.html' %}  
  
{% block content %}  
    <ul class="nav flex-column">  
        <!-- Iterate over object_list -->  
        {% for object in object_list %}  
        <!-- Display Objects -->  
        <li class="nav-item">First Name: {{ object.first_name }}</li>  
        <li class="nav-item">Last Name: {{ object.last_name }}</li>  
        <li class="nav-item">Mobile: {{ object.mobile }}</li>  
        <li class="nav-item"> Email: {{ object.email }}</li>  
  
        <hr/>  
        <!-- If object_list is empty -->  
        {% empty %}  
        <li class="nav-item">No objects Find</li>  
        {% endfor %}  
    </ul>  
  
{% endblock content %}  

现在,我们运行本地主机服务器并发送请求以获取数据。

4.png

详细视图

DetailView与 ListView 不同,因为它显示数据库中表的一个实例。Django自动为每个条目分配一个主键,我们需要在请求中指定<pk> DetailView 将自动执行所有操作。DetailView的实现与ListView相同,我们需要创建modelname_detail.html。

我们来了解一下DetailView的以下实现。

View.py

from django.views.generic.detail import DetailView  
  
class EmployeeDetail(DetailView):  
    model = Employee  

url.py

from django.urls import path  
from .views import EmployeeCreate, EmployeeDetail, EmployeeRetrieve  
  
urlpatterns = [  
    path('', EmployeeCreate.as_view(), name = 'EmployeeCreate'),  
    path('retrieve/', EmployeeRetrieve.as_view(), name = 'EmployeeRetrieve'),  
    path('retrieve/<int:pk>', EmployeeDetail.as_view(), name = 'EmployeeDetail')  
]  

示例应用程序/模板/employee_detail.html

{% extends 'base.html' %}  
  
{% block content %}  
  
    <h1>{{ object.first_name }} {{object.last_name}}</h1>  
  
    <p>{{ object.email }}</p>  
    <p>{{ object.mobile }}</p>  
  
{% endblock content %}  

我们创建了一名新员工,并将 2 作为主键。运行服务器并为请求提供主键。

输出:

5.png

更新视图

UpdateView允许使用更多详细信息从数据库更新表的特定实例。该视图用于更改数据库中的条目。例如,我们要更改用户的名字。我们需要指定模型名称,它会自动完成所有操作。让我们看看下面的UpdateView的实现。

我们已经在模板中创建了employee_form .html 文件。在我们的例子中,它是D:python_projectMyfirstdjangoprojecthellotemplateemployee_form.html>

View.py

from django.views.generic.edit import UpdateView  
class EmployeeUpdate(UpdateView):  
    model = Employee  

网址.py

from django.urls import path  
from .views import EmployeeCreate, EmployeeDetail, EmployeeRetrieve, EmployeeUpdate, EmployeeDelete  
  
urlpatterns = [  
    path('', EmployeeCreate.as_view(), name = 'EmployeeCreate'),  
    path('retrieve/', EmployeeRetrieve.as_view(), name = 'EmployeeRetrieve'),  
    path('<int:pk>', EmployeeDetail.as_view(), name = 'EmployeeDetail'),  
    path('<int:pk>/update/', EmployeeUpdate.as_view(), name = 'EmployeeUpdate'),  
    path('<int:pk>/delete/', EmployeeDelete.as_view(), name = 'EmployeeDelete')  
  
]  

输出:

6.png

我们更新了对象的姓氏。更新后的值将自动添加到数据库中。

7.png

删除视图

DeleteView 允许从数据库中删除表的实例。它用于删除数据库中的条目。

我们只需要指定模型名称,它就会自动完成所有操作。让我们看看下面的UpdateView的实现。

view.py

from django.views.generic.edit DeleteView  
  
class EmployeeDelete(DeleteView):  
    model = Employee  
  
    # here we can specify the URL   
    # to redirect after successful deletion  
    success_url = '/'  

现在,我们创建 URL 路径来映射视图。

url.py

from django.urls import path  
from .views import EmployeeCreate, EmployeeDetail, EmployeeRetrieve, EmployeeUpdate, EmployeeDelete  
  
urlpatterns = [  
    path('', EmployeeCreate.as_view(), name = 'EmployeeCreate'),  
    path('retrieve/', EmployeeRetrieve.as_view(), name = 'EmployeeRetrieve'),  
    path('<int:pk>', EmployeeDetail.as_view(), name = 'EmployeeDetail'),  
    path('<pk>/update/', EmployeeUpdate, name = 'EmployeeUpdate'),  
    path('<pk>/delete/', EmployeeDelete, name = 'EmployeeDelete')  
  
]  

现在,我们创建template/sampleapp/employee_confirm_delete.html。

{% extends 'base.html' %}  
  
{% block content %}  
  
    <form method="post">  
{% csrf_token %}  
      
    <p>Are you sure you want to delete "{{ object }}"?</p>  
  
    <input type="submit" value="Confirm">  
</form>  
  
{% endblock content %}  

输出:

8.png

当我们点击确认按钮时,该对象将被删除并重定向到主页。

我们使用类创建了 CRUD 操作

代码

下面是基于类的通用视图的完整代码。

View.py

from django.shortcuts import redirect, render  
from django.urls import reverse, reverse_lazy  
from django.contrib import messages  
from .models import Employee  
from .forms import EmployeeForm  
from django.views.generic.edit import CreateView, DeleteView, UpdateView  
from django.views.generic.list import ListView  
from django.views.generic.detail import DetailView  
  
class EmployeeCreate(CreateView):  
    model = Employee  
  
    fields = '__all__'  
    success_url = reverse_lazy('sampleapp: EmployeeRetrieve')  
  
class EmployeeRetrieve(ListView):  
    model = Employee  
    success_url = reverse_lazy('sampleapp: EmployeeRetrieve')  
  
class EmployeeDetail(DetailView):  
    model = Employee  
    success_url = reverse_lazy('sampleapp: EmployeeRetrieve')  
  
class EmployeeUpdate(UpdateView):  
    model = Employee  
    template_name_suffix = '_update_form'  
    fields = '__all__'  
    success_url = reverse_lazy('sampleapp: EmployeeRetrieve')  
      
    # def get_success_url(self):  
          
      
      
class EmployeeDelete(DeleteView):  
    model = Employee  
    # here we can specify the URL   
    # to redirect after successful deletion  
    success_url = '/'  

Hello/urls.py

"""Hello URL Configuration  
  
The `urlpatterns` list routes URLs to views. For more information please see:  
    https://docs.djangoproject.com/en/3.1/topics/http/urls/  
Examples:  
Function views  
    1. Add an import:  from my_app import views  
    2. Add a URL to urlpatterns:  path('', views.home, name='home')  
Class-based views  
    1. Add an import:  from other_app.views import Home  
    2. Add a URL to urlpatterns:  path('', Home.as_view(), name='home')  
Including another URLconf  
    1. Import the include() function: from django.urls import include, path  
    2. Add a URL to urlpatterns:  path('blog/', include('blog.urls'))  
"""  
from django.contrib import admin  
from django.urls import path  
from django.urls.conf import include  
  
urlpatterns = [  
    path('admin/', admin.site.urls),  
    path('', include(('sampleapp.urls'), namespace='sampleapp')) 
]  

sampleapp/url.py

from django.urls import path  
from .views import EmployeeCreate, EmployeeDetail, EmployeeRetrieve, EmployeeUpdate, EmployeeDelete  
  
app_name = 'sampleapp'  
urlpatterns = [  
    path('', EmployeeCreate.as_view(), name = 'EmployeeCreate'),  
    path('retrieve/', EmployeeRetrieve.as_view(), name = 'EmployeeRetrieve'),  
    path('<int:pk>', EmployeeDetail.as_view(), name = 'EmployeeDetail'),  
    path('<int:pk>/update/', EmployeeUpdate.as_view(), name = 'EmployeeUpdate'),  
    path('<int:pk>/delete/', EmployeeDelete.as_view(), name = 'EmployeeDelete')  
  
]  

template/base.html

<!doctype html>  
<html lang="en">  
  <head>  
    <!-- Required meta tags -->  
    <meta charset="utf-8">  
    <meta name="viewport" content="width=device-width, initial-scale=1">  
  
    <!-- Bootstrap CSS -->  
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">  
  
    <title>Register Page</title>  
  </head>  
  <body>  
  <div class = 'col-md-8'>  
     {% if messages %}  
        <ul>   
            {% for message in messages %}  
              <div class = 'alert alert-{{message.tags}}'>  
                {{ message }}   
              </div>  
              {% endfor %}  
        </ul>   
    {% endif %}   
  </div>  
  {% block content %}  
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM" crossorigin="anonymous"></script>  
  
      
    {% endblock content %}  
  </body>  
</html>  

template/sampleapp/employe_list

{% extends 'base.html' %}  
  
{% block content %}  
  
<table class="table table-borderless">  
    <thead class="border-bottom font-weight-bold">  
        <tr>  
            <td>First Name</td>  
            <td>Last Name</td>  
            <td>Mobile</td>  
            <td>Email</td>  
                {% comment %} <a href="{% url 'EmployeeRetrieve' %}" class="btn btn-outline-success">  
                    <i class="fas fa-plus"></i> Add New {% endcomment %}  
                </a>  
            </td>  
        </tr>  
    </thead>  
  
    {% for object in object_list %}  
        <!-- Display Objects -->  
        <tr>  
                <td>{{ object.first_name }}</td>  
                <td> {{object.last_name }}</td>  
                <td> {{object.mobile }}</td>  
                <td>{{object.email }} </td>  
  
            <td>  
            <td><button><a href = '/{{object.pk}}/delete' class = 'class="btn text-secondary px-0'> Delete  
            </a></button></td>  
  
            <td><button><a href = '/{{object.pk}}/update' class = 'class="btn text-secondary px-0'> Update  
            </a></button></td>  
    {% endfor %}  
  
</table>  

template/sampleapp/employe_detail

{% extends 'base.html' %}  
  
{% block content %}  
  
    <h1>{{ object.first_name }} {{object.last_name}}</h1>  
  
    <p>{{ object.email }}</p>  
    <p>{{ object.mobile }}</p>  
  
    <td><button><a href = '/{{object.pk}}/delete' class = 'class="btn text-secondary px-0'> Delete  
    </a></button></td>  
  
    <td><button><a href = '/{{object.pk}}/update' class = 'class="btn text-secondary px-0'> Update  
  </a></button></td>  
{% endblock content %}  

template/sampleapp/employe_update_form.html

{% extends 'base.html' %}  
  
{% block content %}  
    <form method="post">  
    {% csrf_token %}  
        {{ form.as_p }}  
        <input type="submit" value="Update">  
    </form>  
{% endblock content %}  

template/sampleapp/employe_confirm_delete.html

{% extends 'base.html' %}  
  
{% block content %}  
  
    <form method="post">{% csrf_token %}  
      
    <p>Are you sure you want to delete "{{ object }}"?</p>  
  
    <input type="submit" value="Confirm">  
</form>  
{% endblock content %}  

结论

在本教程中,我们讨论了基于类的视图以及它们与基于函数的视图有何不同。我们已经使用内置视图实现了增删改查操作。

CBV 是从现有视图继承并覆盖属性(template_name)或方法的强大方法。

这些视图已经预先编写了代码,因此我们不需要进行硬编码。但不建议初学者这样做,因为这无助于理解 Django 的核心深度。一旦您熟悉了基于函数的视图的概念。您可以转向基于阶级的观点。

标签: django语言, django教程, django技术, django学习, django学习教程, django下载, django开发, django入门教程, django进阶教程, django高级教程, django面试题, django笔试题, django编程思想