Django自学笔记 6-2 拓展CBVs(Class-based views)

————总目录——前言——框架版本————

======================= 大爽歌作,made by big shuang =======================

二、拓展CBVs(Class-based views)

一般而言,直接使用原生的Class-based views,能展现的样式和内容是固定的。
为了根据实际情况去定制View,我们需要继承django自带的View并修改。
在修改之前,我们需要先了解下CBVs。

1 Class-based views常用属性和常用方法

model

视图将为其显示数据的模型。(The model that this view will display data for.)

form_class

要实例化的表单类,视图将会根据表单来展示字段。

fields

需要在视图上展示的字段名称组成的列表

补充: form_class 和 fields 必须且只能设置一个。

template_name

由字符串定义的要使用的模板的全名。不定义模板名将引发django.core.exceptions.ImproperlyConfigured异常。

success_url

成功处理表单时重定向到的URL。

context_object_name

context中使用的变量的名称。一般是form

get_context_data()

Returns context data for displaying the object.
The base implementation of this method requires that the self.object attribute be set by the view (even if None). Be sure to do this if you are using this mixin without one of the built-in views that does so.
It returns a dictionary with these contents:
object: The object that this view is displaying (self.object).
context_object_name: self.object will also be stored under the name returned by get_context_object_name(), which defaults to the lowercased version of the model name.

返回用于显示对象的context数据,返回包含以下内容的词典:
object:此视图显示的对象(self.object).
context_object_nameself.object还将存储在get_context_object_name()返回的名称下,该名称默认为模型名称的小写版本。

PS: 需要修改context数据,可重写此方法
例子如下(出处:adding-extra-context

class PublisherDetail(DetailView):

    model = Publisher

    def get_context_data(self, **kwargs):
        # Call the base implementation first to get a context
        context = super().get_context_data(**kwargs)
        # Add in a QuerySet of all the books
        context['book_list'] = Book.objects.all()
        return context

2 实例

拓展CreateView

欲实现:学生注册时,学生选择年级后注册,自动根据年级按序生成年级子学号
具体来说,一个年级没有学生的话,那么新注册的学生学号就是000001
一个年级有学生的话,取出所有学生里面的最大学号,新注册的学生学号就是最大学号增加1
此时my_app/forms.py

#usr/bin/env python
#-*- coding:utf-8- -*-
from django import forms
from .models import Student


class RegisterForm(forms.ModelForm):
    confirm_password = forms.CharField(widget=forms.PasswordInput())

    class Meta:
        model = Student
        fields = ('grade',
                  'name',
                  'password',
                  'confirm_password',
                  'gender',
                  'birthday',
                  'email',
                  'info')

    def clean(self):
        cleaned_data = super(RegisterForm, self).clean()
        password = cleaned_data.get('password')
        confirm_password = cleaned_data.get('confirm_password')
        if confirm_password != password:
            self.add_error('confirm_password', 'Password does not match.')

my_app/views/register.py

from django.shortcuts import render
from django.http.response import HttpResponse,HttpResponseRedirect
from .models import Student
from django.views.generic import CreateView
from .forms import RegisterForm


class CreateStudentView(CreateView):
    model = Student
    form_class = RegisterForm
    # fields = "__all__"
    template_name = "register.html"
    success_url = "login"

    def post(self, request, *args, **kwargs):
        form = self.get_form()

        if form.is_valid():
            return self.form_valid(form)
        else:
            return self.form_invalid(form)

    def form_valid(self, form):
        # 学生注册时选定年级自动生成学号
        grade = form.cleaned_data["grade"]
        # order_by默认升序排列,number前的负号表示降序排列
        student_set = Student.objects.filter(grade=grade).order_by("-number")
        if student_set.count() > 0:
            last_student = student_set[0]
            new_number = str(int(last_student.number) + 1)
            for i in range(6 - len(new_number)):
                new_number = "0" + new_number
        else:
            new_number = "000001"

        # Create, but don't save the new student instance.
        new_student = form.save(commit=False)
        # Modify the student
        new_student.number = new_number
        # Save the new instance.
        new_student.save()
        # Now, save the many-to-many data for the form.
        form.save_m2m()

        self.object = new_student
        return HttpResponseRedirect(self.get_success_url())

对应urls.py里面的urlpatterns变量,添加对应的urlpattern如下

from django.urls import path

from my_app.views import login, register
from my_app import view

urlpatterns = [
    path('login/', login.page, name="login"),
    path('hello/', view.hello),

    path('register', register.CreateStudentView.as_view(),
         name="register"),
]

register.html6-1 基于类的视图(Class-based views)介绍
Student模型见Django自学笔记 4-1 模型(Models)介绍中的示例。
其他代码见本专栏之前博客(实际上本文用不到)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章