django 基于类的视图

原创博客,转载请只用写本文url链即可。

View

最基本的视图。除了get,post等方法,还能用几个Mixin以外,其他和函数差不多。

导入:

from django.views import View

ListView

定义这个类视图必须写如下两个参数或者之一:model or queryset or get_queryset()。我比较推荐用querysetqueryset就是写一个queryset,字面意思。model就是模型名。get_queryset()就是返回一个queryset。还是觉得用queryset简单,无痛。

使用如下:

class IndexView(ListView):
    queryset = User.objects.all()  
    template_name = 'index.html'   # mypp/user_list.html
    context_object_name = 'ones'   # 如果不设置,它的默认名字就是user_list.html
    paginate_by = 3                # 每页显示多少个数据
    # page_kwarg = 'page'          # 这个参数是查询第几页的参数名,不写默认是page
    # ordering = None              # 排序规则,传入一个元组
    # paginator_class = Paginator  # 这个可以不用写,这个是django默认的分页方式
    # extra_context = {"hello": "world!"} # 添加额外参数,也可以使用get_context_data函数来添加额外参数,推荐使用函数方式,这样可读性更好。  

    def get_context_data(self, **kwargs):
        # 这个方法就是用来给添加新的模板渲染变量的
        context = super().get_context_data(**kwargs)
        context['hello'] = "world!"
        return context

get_context_data再推荐一种写法,这个写法是源码复用时候的写法:

    def get_context_data(self, **kwargs):
        kwargs['hello'] = 'world'
        return super().get_context_data(**kwargs)

DetailView

获得模型中的单一数据。

使用代码如下:

class DetaiPageView(DetailView):
    queryset = User.objects.all()    # model or queryset or get_queryset()
    template_name = 'detail.html'   # 如果不设置,它的默认名字就是user_detail.html
    context_object_name = 'one'

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context['hello'] = "world"
        return context

默认是找主键,也可以自定义参数,如果要自定义参数,需要保证模型中有slug字段,然后在urls.py中这么写:

path("detail/<slug>/", views.DetaiPageView.as_view(), name="detail"),
# path("detail/<pk>/", views.DetaiPageView.as_view(), name="detail"), 如果写pk就是找主键了,注意,这里只能找pk或者slug,不能写id,username之类的字段

注意:urls.py中参数变量只能是pk或者slug字段。所以写pk或者slug。如果你想使用其他参数,比如username作为这个变量,你可以设置这个属性:

	slug_field = "username"

然后在urls.py中还是要写slug:

path("detail/<slug>/", views.DetaiPageView.as_view(), name="detail"),

TemplateView

这个类方法很简单,如果你会用ListView和DetailView,这个类会很好上手。

最简单的使用:

path("template/", TemplateView.as_view(template_name="template.html"), name="template"),

一行代码直接解决一个页面。

如果想要给模板加上变量参数可以这么写:

path("template/", TemplateView.as_view(template_name="template.html", extra_context={"hello": "world"}), name="template"),

RedirectView

class RedirectPageView(RedirectView):
    parmanent = False            # 是否是永久重定向,就是状态码会不同,默认是False
    pattern_name = 'detail'      # name值
    # url 属性 : 这个属性是直接写url链接跳转,不过不建议,就写上面的name值就可以了

如果重定向的页面有参数的话,这个方法是我发现的,不过个人认为有点蹩脚。所以,呃,不是很推荐使用,但是如果要有重定向有参数的需求的时候,可以这么写,只需要把参数这么写:

class RedirectPageView(RedirectView):
    pattern_name = 'detail'  
    
    def get_redirect_url(self):
        return super().get_redirect_url(pk=1)

当然,能一行代码搞定的事情为什么要写几行呢,来吧,一行重定向:

path("redirect/", views.RedirectView.as_view(pattern_name="template"), name="redirect"),

FormView

这么写:

from django.views.generic import FormView
from django.urls import reverse_lazy
from myapp.forms import UserForm

class FormPageView(FormView):
    success_url = reverse_lazy("template")
    form_class = UserForm
    template_name = "forms.html"
    # initial = {"username": "catfish"}  设置初始值
    # prefix = "catfish"     设置表单name前缀,比如,如果设置的是catfish,则name为"catfish-username"

这里如果不用reverse_lazy用reverse会报错:

django.core.exceptions.ImproperlyConfigured: The included URLconf 'drf_project.urls' does not appear to have any patterns in it. If you see valid patterns in the file then the issue is probably caused by a circular import.

原因就是因为在调用urls.py之前使用了reverse反转了一个空的url链接,所以会报错。而reverse_lazy可以使它延迟在加载urls.py之后再加载。一般来说,在FBV中使用reverse,在CBV中使用reverse_lazy

所以,如果是在类属性中调用reverse会报错,这个时候我们需要使用reverse_lazy使它延迟加载,如果是在类的方法中使用reverse是不会报错的。因为方法是在它被调用的时候加载,而类属性是加载类的时候就会加载。加载类的时候加载在urls.py之前,而调用类中的方法是在访问页面的时候,也就是被调用的时候被加载,此时的urls.py已经被加载了,所以不会报错。

说了这么多,来个总结:在类视图的属性中使用reverse_lazy,在类视图的方法和函数视图中可以使用reverse

CreateView

这个方法就是提交表单并创建一个对象。使用代码如下:

class CreatePageView(CreateView):
    form_class = UserForm
    template_name = "create.html"
    success_url = '/'

推荐这么写,这样可以用到表单的验证。也可以定义model和field字段指定然后创建,不过使用model和field字段只会在已能输入的字段上进行models.py里面的验证,不能输入的字段中不能使用该验证,会默认保存为一个空的字符串。

这个类方法的特色是,多了个self.object属性,如果表单识别验证通过会出现这个属性,如果不通过则不会返回。

extra_context和get_context_data适用于这个方法。urls.py代码如下:

path("create/", views.CreatePageView.as_view(), name="create"),

DeleteView

使用代码如下:

from django.utils.decorators import method_decorator
from django.views.decorators.csrf import csrf_exempt
from django.views.generic import DeleteView

@method_decorator(csrf_exempt, name='dispatch')
class DeletePageView(DeleteView):
    queryset = User.objects.all()
    # 或者定义:slug_field
    success_url = "/"

DeleteView用途则用于使用post请求删除相关的数据。所以,我这里避开了csrf验证。get请求没什么用。urls.py代码如下:

path("delete/<pk>/", views.DeletePageView.as_view(), name="delete"),

UpdateView

用于更新数据,代码如下:

class UpdatePageView(UpdateView):
    form_class = UserForm # 一定要写queryset,不能用form_class代替
    queryset = User.objects.all()
    template_name = "update.html"
    context_object_name = 'one'
    success_url = '/'

urls.py代码如下:

path("update/<pk>/", views.UpdatePageView.as_view(), name="update"),
posted @ 2021-05-24 17:32  小默同学  阅读(261)  评论(0编辑  收藏  举报