102django_cbv
admin
2023-07-08 11:44:10
0次

 

目录

django.views.generic.TemplateView.. 1

django.views.generic.View.. 2

类的继承和覆盖:... 5

自定义LoginRequiredMixin:... 5

通用视图:... 6

django.views.generic.ListView.. 6

django.views.generic.DetailView.. 8

django.views.generic.FormView:... 9

django.views.generic.CreateView:... 9

django.views.generic.UpdateView:... 9

 

 

 

cbv,class based view:

基于类的视图,使编写view更简洁,有复杂的继承关系;

 

CBV和FBV两者各有优劣;

 

102django_cbv

 

 

 

django.views.generic.TemplateView

 

102django_cbv

UML图;

Mixin增强功能,提供一些方法,如TemplateResponseMixin提供了render_to_response()渲染模板,ContextMixin提供get_context_data();

View提供get,post访问入口;

 

 

例,ver1:

def about(request):   #ver1,FBV用法

    return render(request, 'blog/about.html')

 

url(r'^about/', views.about, name='about'),

 

 

例,ver2:

from django.views.generic import TemplateView

 

app_name = 'blog'

 

urlpatterns = [

    url(r'^$', views.index, name='index'),

    url(r'^login/', views.auth_login, name='login'),

    url(r'^logout/', views.auth_logout, name='logout'),

    # url(r'^about/', views.about, name='about'),

    url(r'^about/', TemplateView.as_view(template_name='blog/about.html')),   #ver2,CBV用法1

]

 

 

例,ver3:

from django.views.generic import TemplateView

 

class AboutView(TemplateView):   #ver3,CBV用法2

template_name = 'blog/about.html'

 

 

url(r'^about/', AboutView.as_view()),

 

 

django.views.generic.View

 

View源码:

该类在没更改原来django逻辑的情况下,可用于编写view,每个http请求会使用对应类的同名的方法进行处理;

class View(object):

    """

    Intentionally simple parent class for all views. Only implements

    dispatch-by-method and simple sanity checking.

    """

 

    http_method_names = ['get', 'post', 'put', 'patch', 'delete', 'head', 'options', 'trace']

 

    def __init__(self, **kwargs):   #检查as_view()传入的参数是否在类中定义

        """

        Constructor. Called in the URLconf; can contain helpful extra

        keyword arguments, and other things.

        """

        # Go through keyword arguments, and either save their values to our

        # instance, or raise an error.

        for key, value in six.iteritems(kwargs):

            setattr(self, key, value)

 

@classonlymethod

    def as_view(cls, **initkwargs):   #返回的是一个函数对象(装饰器);template_name=’blog/about.html’模板名作为参数传,或在类属性中定义,传入的参数可覆盖类中定义的属性

        """

        Main entry point for a request-response process.

        """

        for key in initkwargs:

            if key in cls.http_method_names:

                raise TypeError("You tried to pass in the %s method name as a "

                                "keyword argument to %s(). Don't do that."

                                % (key, cls.__name__))

            if not hasattr(cls, key):

                raise TypeError("%s() received an invalid keyword %r. as_view "

                                "only accepts arguments that are already "

                                "attributes of the class." % (cls.__name__, key))

 

        def view(request, *args, **kwargs):

            self = cls(**initkwargs)

            if hasattr(self, 'get') and not hasattr(self, 'head'):

                self.head = self.get

            self.request = request

            self.args = args

            self.kwargs = kwargs

            return self.dispatch(request, *args, **kwargs)

        view.view_class = cls

        view.view_initkwargs = initkwargs

 

        # take name and docstring from class

        update_wrapper(view, cls, updated=())

 

        # and possible attributes set by decorators

        # like csrf_exempt from dispatch

        update_wrapper(view, cls.dispatch, assigned=())

        return view

 

    def dispatch(self, request, *args, **kwargs):   #根据用户的request method路由到get、post方法

        # Try to dispatch to the right method; if a method doesn't exist,

        # defer to the error handler. Also defer to the error handler if the

        # request method isn't on the approved list.

        if request.method.lower() in self.http_method_names:

            handler = getattr(self, request.method.lower(), self.http_method_not_allowed)

        else:

            handler = self.http_method_not_allowed

        return handler(request, *args, **kwargs)

 

    def http_method_not_allowed(self, request, *args, **kwargs):

        logger.warning(

            'Method Not Allowed (%s): %s', request.method, request.path,

            extra={'status_code': 405, 'request': request}

        )

        return http.HttpResponseNotAllowed(self._allowed_methods())

 

    def options(self, request, *args, **kwargs):

        """

        Handles responding to requests for the OPTIONS HTTP verb.

        """

        response = http.HttpResponse()

        response['Allow'] = ', '.join(self._allowed_methods())

        response['Content-Length'] = '0'

        return response

 

    def _allowed_methods(self):

        return [m.upper() for m in self.http_method_names if hasattr(self, m)]

 

 

例,ver1,FBV:

def my_view(request):

    if request.method == 'GET':

        return HttpResponse('get it')

    elif request.method == 'POST':

        return HttpResponse('post it')

    elif request.method == 'HEAD':

        return HttpResponse('head it')

 

 

例,ver2,CBV,省去了if判断:

 

from django.views.generic import View

 

class MyView(View):

 

    def get(self, request):

        return HttpResponse('get it')

 

    def post(self, request):

        return HttpResponse('post it')

 

    def head(self, request):

        return HttpResponse('head it')

 

 

    # url(r'^myview', views.my_view),

    url(r'^myview', MyView.as_view()),

 

 

类的继承和覆盖:

 

class GreetingView(View):

    greeting = 'good day'

    def get(self, request):

        return HttpResponse(self.greeting)

 

class MorningGreetingView(GreetingView):

    greeting = 'morning to yo'

 

 

 

自定义LoginRequiredMixin:

 

class LoginRequiredMixin:

    @classmethod

    def as_view(cls, **initkwargs):

        view = super(LoginRequiredMixin, cls).as_view(**initkwargs)

        return login_required(view)

   

class MyView(LoginRequiredMixin, View):

    pass

 

 

装饰类:

from django.utils.decorators import method_decorator

 

class ProtectedView(TemplateView):

    template_name = 'blog/about.html'

   

    @method_decorator(login_required)

    def dispatch(self, *args, **kwargs):

        return super(ProtectedView, self).dispatch(*args, **kwargs)

 

 

 

通用视图:

 

generic class based view和class based view概念上不是一回事;

class based view是用类的方式写view;

generic class based view是用class based view方式将常用的CRUD封装成可扩展的类,使用时直接继承,快速实现;

 

 

django.views.generic.ListView

 

多对象;

默认提供的上下文是object_list,也可用context_object_name指定;

queryset、get_queryset、model;

可指定template_name;

 

102django_cbv

 

例,ver1:

def publisher_list(request):

    publishers = Publisher.objects.all()

    return render(request, 'books/publishers.html', {'publishers': publishers})

 

例,ver2:

from django.views.generic import ListView

 

class PublisherList(ListView):   #默认去找suffix为list的模板,即publisher_list.html;publisher_list.html模板;默认的context为object_list

    model = Publisher   #返回Publisher.object.all(),多对象

    # template_name = 'books/publishers.html'   #

         # context_object_name =    #提供上下文

         # queryset = Publisher.objects.all()   #model|queryset|get_queryset()三者关系

         # def get_queryset(self):

         #       return Publisher.objects.all()

 

 

   

            {% for publisher in object_list %}

           

    {{ publisher }}

            {% endfor %}

       

 

 

    # url(r'^$', views.publisher_list, name='publishers'),

    url(r'^$', PublisherList.as_view(), name='publisher'),

 

 

django.views.generic.DetailView

 

单个对象的详情;

get_context_data();

context_object_name;

 

102django_cbv

 

   

           

    {{ publisher }}

            {% for book in book_list %}

            {{ book }}

            {{ book.publisher }}

            {% endfor %}

       

 

 

from django.views.generic import DetailView

from .models import Book

 

class PublisherDetail(DetailView):

    model = Publisher

    context_object_name = 'publisher'

 

    def get_context_data(self, **kwargs):

        context = super(PublisherDetail, self).get_context_data(**kwargs)

        context['book_list'] = Book.objects.all()

        return context

 

 

    url(r'^$', PublisherList.as_view(), name='publisher'),

    url(r'^(?P[0-9]+)/$', PublisherDetail.as_view()),

 

 

django.views.generic.FormView:

 

class PublisherForm(forms.Form):

    name = forms.CharField(label=_('Your name'), max_length=30)

    address = forms.CharField(max_length=50)

    city = forms.CharField(max_length=60)

    state_province = forms.CharField(max_length=30)

    country = forms.CharField(max_length=20)

    website = forms.CharField(max_length=50)

 

    def send_mail(self):

        print('~~~~~~~~~~~send_mail()   OK')

 

 

from django.views.generic import FormView

 

class PublisherView(FormView):

    form_class = PublisherForm

    template_name = 'books/books_add.html'

    success_url = '/books/'

 

    def form_valid(self, form):

        form.send_mail()

        return super(PublisherView, self).form_valid(form)

 

 

    url(r'^$', PublisherList.as_view(), name='publisher'),

url(r'^add', PublisherView.as_view()),

 

 

django.views.generic.CreateView:

 

根据model和fields动态构建form,另form_class = forms.AuthorForm等价于model和fields;

model + fields = form_class,另get_form_class、get_form;

template_name,不指定默认找suffix为_form.html;

success_url,get_success_url;

form_valid()、form_invalid(),注意重写都要调用父类方法;

get_context_data;

success_message、get_success_message;

 

102django_cbv

 

from django.views.generic import CreateView

from .models import Author

 

class AuthorCreate(CreateView):

    model = Author

    fields = ['first_name', 'last_name', 'email']

    success_url = '/books/'

 

    def form_valid(self, form):

        return super().form_valid(form)

 

    def get_context_data(self, **kwargs):

        context = {'extra': 'some context'}

        kwargs.update(context)

        return super().get_context_data(**kwargs)

 

 

    url(r'^author/', AuthorCreate.as_view()),

 

 

django.views.generic.UpdateView:

 

102django_cbv

 

django.views.generic.DeleteView:

 

要有删除确认页面;

 

102django_cbv

 

 


 

 


上一篇:103django_rest-framework

下一篇:100django_admin

相关内容

热门资讯

空调连续工作多久需要停机休息 空调连续工作的时间取决于多个因素,包括空调的型号、功率、使用环境和维护情况等。一般来说,空调可以连续...
空调哪个符号是除湿的 空调除湿功能通常用一个水滴形状的符号表示。不同品牌和型号的空调遥控器可能会有所差异,但一般来说,除湿...
格力空调多长时间加一次氟利昂 1、一般情况下,空调对氟利昂的使用量是非常小的,所以在空调使用了四年左右的时候再考虑加也没问题。2、...
空调用多长时间需要加氟一次 一般情况下是五年。当出现以下这几种情况时,空调才需要加氟。1、空调的室内机和室外机各有两个接口,当接...
格调生活·C标思享荟:卡萨帝在... 9月12日的郑州龙湖金融岛,夜风轻拂,灯光璀璨。“C标时刻共传奇——卡萨帝思享荟暨20周年品牌盛典郑...
品牌价值破千亿、高端份额持续领... 9月12日,“C标时刻共传奇——卡萨帝思享荟暨20周年品牌盛典郑州站”在郑州龙湖金融岛举办。2026...
空调主板坏了修800还是换新的 空调主板坏了是修还是换新,需要考虑多个因素,以下是一些建议:1. 维修成本:如果维修费用较低,比如 ...
空调开多久需要休息多长时间 问题:空调开多久需要休息多长时间回答:1、在使用空调的过程中,一般空调开7~8个小时左右需要休息2~...
中央空调多长时间清洗一次 1、一般空调开机前清洗一次即可,空调开机中间时段再清洗一次,空调关机时清洗一次,这样比较合理。2、空...
中央空调氟利昂多久加一次 看空调制热和制冷程度,很多人的观点认为氟利昂必须一年放一次,其实这个观点是错误的,理解上面有点偏差,...