一、CBV模式和FBV模式

FBV模式(function base views):就是在视图里使用函数处理请求

CBV模式(class base views) 就是在视图里使用类处理请求

CBV模式的优点主要下面两种:

        提高了代码的复用性,可以使用面向对象的技术,比如Mixin(多继承)

        可以用不同的函数针对不同的HTTP方法处理,而不是通过很多if判断,提高代码可读性

urls.py文件:

from django.conf.urls import urlfrom django.contrib import adminfrom app01 import viewsurlpatterns = [    url(r'^admin/', admin.site.urls),    url(r'^login/', views.LoginView.as_view()),          # view()===self.dispatch()===self.get()]

views.py文件:

from django.shortcuts import render, HttpResponsefrom django.views import Viewclass LoginView(View):    def dispatch(self, request, *args, **kwargs):        ret=super().dispatch(request, *args, **kwargs)      #super():python3中继承父类的方法,否则会覆盖父类的方法        return ret    def get(self,request):        return render(request, "login.html")    def post(self,request):        user=request.POST.get("user")        return HttpResponse(user)        #视图类定义各种方法,代替了在视图函数的if请求方式判断,# 如果没有自定义dispatch方法,就执行父类的dispatch方法,然后执行对应的get或post方法,#如果有自定义dispatch方法,就执行自定义的dispatch方法,但是自定义的dispatch方法必须继承父类的方法

二、ModelForm

ModelForm用起来是非常方便的,比如增加修改之类的操作。但是也带来额外不好的地方,model和form之间耦合了。如果不耦合的话,mf.save()方法也无法直接提交保存。 但是耦合的话使用场景通常局限用于小程序,写大程序就最好不用了。

1、创建modelform

from django.forms import ModelForm#在视图函数中,定义一个类,比如就叫StudentList,这个类要继承ModelForm,在这个类中再写一个原类Meta(规定写法,并注意首字母是大写的)#在这个原类中,有以下属性(部分):class StudentList(ModelForm):    class Meta:        model =Student #对应的Model中的类        fields = "__all__" #字段,如果是__all__,就是表示列出所有的字段        exclude = None #排除的字段        #error_messages用法:        error_messages = {        'name':{'required':"用户名不能为空",},        'age':{'required':"年龄不能为空",},        }        #widgets用法,比如把输入用户名的input框给为Textarea        #首先得导入模块        from django.forms import widgets as wid #因为重名,所以起个别名        widgets = {        "name":wid.Textarea(attrs={"class":"c1"}) #还可以自定义属性        }        #labels,自定义在前端显示的名字        labels= {        "name":"用户名"        }

2、视图函数

views.py文件:

from django.shortcuts import render,HttpResponse,redirectfrom django.forms import ModelFormfrom app01 import modelsdef test(request):    # model_form = models.Student    model_form = models.Student.objects.all()    return render(request,'test.html',{'model_form':model_form})    class StudentList(ModelForm):    class Meta:        model = models.Student #对应的Model中的类        fields = "__all__" #字段,如果是__all__,就是表示列出所有的字段        exclude = None #排除的字段        labels = None #提示信息        help_texts = None #帮助提示信息        widgets = None #自定义插件        error_messages = None #自定义错误信息        #error_messages用法:        error_messages = {        'name':{'required':"用户名不能为空",},        'age':{'required':"年龄不能为空",},        }        #widgets用法,比如把输入用户名的input框给为Textarea        #首先得导入模块        from django.forms import widgets as wid #因为重名,所以起个别名        widgets = {        "name":wid.Textarea        }        #labels,自定义在前端显示的名字        labels= {        "name":"用户名"        }        def student(request):    if request.method == 'GET':        student_list = StudentList()        return render(request,'student.html',{'student_list':student_list})    else:        student_list = StudentList(request.POST)        if student_list.is_valid():            student_list.save()            return render(request,'student.html',{'student_list':student_list})            def student_edit(request,pk):    obj = models.Student.objects.filter(pk=pk).first()    if not obj:        return redirect('test')    if request.method == "GET":        student_list = StudentList(instance=obj)        return render(request,'student_edit.html',{'student_list':student_list})    else:        student_list = StudentList(request.POST,instance=obj)        if student_list.is_valid():            student_list.save()            return render(request,'student_edit.html',{'student_list':student_list})

3、student.html页面

    

student

    
        {% csrf_token %}        {# {
{ student_list.as_p }}#}                         {#可以用as_p显示全部#}        {% for student in student_list %}            
                {# 拿到数据字段的verbose_name,没有就默认显示字段名 #}                
{
{ student.label }}                
{
{ student }}                    {% endfor %}        
            
            现在还缺一个input框的form-contral样式,可以考虑在后台的widget里面添加比如这样:from django.forms import widgets as wid        #因为重名,所以起个别名widgets = {"name":wid.TextInput(attrs={'class':'form-control'}),"age":wid.NumberInput(attrs={'class':'form-control'}),"email":wid.EmailInput(attrs={'class':'form-control'})}

4、基于form组件和model form组件的对比

models.py文件:

from django.db import modelsclass Author(models.Model):    nid = models.AutoField(primary_key=True)    name=models.CharField( max_length=32)    age=models.IntegerField()    authorDetail=models.OneToOneField(to="AuthorDetail",on_delete=models.CASCADE)    def __str__(self):        return self.nameclass AuthorDetail(models.Model):    nid = models.AutoField(primary_key=True)    birthday=models.DateField()    telephone=models.BigIntegerField()    addr=models.CharField( max_length=64)class Publish(models.Model):    nid = models.AutoField(primary_key=True)    name=models.CharField( max_length=32)    city=models.CharField( max_length=32)    email=models.EmailField()    def __str__(self):        return self.nameclass Book(models.Model):    nid = models.AutoField(primary_key=True)    title = models.CharField( max_length=32)    publishDate=models.DateField()    price=models.DecimalField(max_digits=5,decimal_places=2)    publish=models.ForeignKey(to="Publish",to_field="nid",on_delete=models.CASCADE)    authors=models.ManyToManyField(to='Author',)    # 与Author表建立多对多的关系,ManyToManyField可以建在两个模型中的任意一个,自动创建第三张表

#执行下面python语句生成相关表(数据迁移)

python3 manage.py makemigrationspython3 manage.py migrate

urls.py文件:

from django.conf.urls import urlfrom django.contrib import adminfrom app01 import viewsurlpatterns = [    url(r'^admin/', admin.site.urls),    url(r'^add_book/', views.AddBookView.as_view()),    url(r'^edit_book/(\d+)', views.EditBookView.as_view()),]

views.py文件:

from django.shortcuts import render,HttpResponsefrom django.views import Viewfrom django import formsfrom .models import Publish,Author,Book#########################################################之前学习的基于form组件#########################################################class BookForm(forms.Form):    title=forms.CharField()    price=forms.DecimalField()    publishDate=forms.DateField()    #state=forms.ChoiceField(choices=[(1,"已出版"),(2,"未出版")])    publish=forms.ModelChoiceField(queryset=Publish.objects.all())    authors=forms.ModelMultipleChoiceField(queryset=Author.objects.all())    #########################################################基于model form组件#########################################################from django.forms import ModelFormclass BookModelForm(ModelForm):    class Meta:        model=Book                              ##对应的Model中的Book类        fields="__all__"class AddBookView(View):    def get(self,request):        form=BookModelForm()        return render(request,"addbook.html",locals())    def post(self,request):        form=BookModelForm(request.POST)        if form.is_valid():            # print("cleaned_data:",form.cleaned_data)            # form.cleaned_data.pop("authors")            # Book.objects.create(**form.cleaned_data)            #基于form实现的添加记录            form.save()                                         #基于model form,会自动添加记录            return HttpResponse("OK")        else:            print(form.cleaned_data)            print(form.errors)        return HttpResponse("OK")class EditBookView(View):    def get(self,request,id):        edit_book=Book.objects.get(pk=id)        form = BookModelForm(instance=edit_book)                 #编辑的时候需要一个instance,让instance=一个你要编辑的那个对象        return render(request,"editbook.html",locals())    def post(self,request,id):        edit_book = Book.objects.get(pk=id)        form=BookModelForm(request.POST,instance=edit_book)        if form.is_valid():            form.save()            return HttpResponse("OK")        else:            print(form.cleaned_data)            print(form.errors)        return HttpResponse("OK")
html页面:

    
    
Title
    {% csrf_token %}    {
{ form.as_p }}