Django -- Generic Views - Editing Views

表单处理流程

  • HTTTP GET
    • 渲染空表单 Form()
    • 渲染带初始值的表单 Form(initial={'key': 'val'})
  • HTTP POST
    • 提交无效数据 Form(request.POST) 重新渲染表单,并显示错误信息
    • 提交有效数据 request.cleaned_data 处理表单,并重定向

FormView 基础类视图

from myapp.forms import ContactForm
from django.views.generic.edit import FormView

class ContactView(FormView):
    template_name = 'contact.html'
    form_class = ContactForm
    success_url = '/thanks/'

    def form_valid(self, form):
        # 当表单验证通过时,调用该方法
        # 默认实现是:重定向到 success_url
        # This method is called when valid form data has been POSTed.
        # It should return an HttpResponse.
        form.send_email()
        return super().form_valid(form)  # 返回一个 HttpResponse: redirect(success_url)

Edit Views(Model forms)

  • CreateView
  • UpdateView
  • DeleteView

只要指定要操作的某一 Model 的 objec, 类视图就可以自动生成 ModelForm, 指定 object 的方法

属性:

  • model
  • queryset

方法:.get_queryset() 返回一个 object


  • 可以不用为 CreateView, UpdateView 指定 success_url: 因为它会从 Model 中的 .get_absolute_url() 获取
  • 这些根据 Model 生成表单的类视图,其 .form_valid() 会自动将表单数据保存到 Model 中 (调用 form.save())
# models.py
from django.urls import reverse
from django.db import models

class Author(models.Model):
    name = models.CharField(max_length=200)

    def get_absolute_url(self):
        return reverse('author-detail', kwargs={'pk': self.pk})

# views.py
from django.views.generic.edit import CreateView, UpdateView, DeleteView
from django.urls import reverse_lazy
from myapp.models import Author

class AuthorCreate(CreateView):
    model = Author
    fields = ['name']

class AuthorUpdate(UpdateView):
    model = Author
    fields = ['name']

class AuthorDelete(DeleteView):
    model = Author
    success_url = reverse_lazy('author-list')

# urls.py
from django.urls import path
from myapp.views import AuthorCreate, AuthorUpdate, AuthorDelete

urlpatterns = [
    # ...
    path('author/add/', AuthorCreate.as_view(), name='author-add'),
    path('author//', AuthorUpdate.as_view(), name='author-update'),
    path('author//delete/', AuthorDelete.as_view(), name='author-delete'),
]

总结

属性:

  • model
  • fields
  • form_class
  • success_url 可以从 Model 的 .get_absolute_url() 中获取
  • template_name_suffix
  • tempalte_name

方法:form_valid() 会自动保存表单数据到数据库,并进行重定向


需要使用 reverse_lazy() 的3中情况:(原因是 此时 URLConf 还未导入)

  • 在通用视图中
  • 在装饰器中
  • 函数为参数提供默认值是 def func(url=reverse_lazy('login'))

从 Python 官方文档的 Python Tutorial 中的函数一章可以知道:函数默认参数的值是在执行到函数定义是确定的,而非在函数调用时确定的

使用属性:form_class 指定自定义的 django.forms.Form (和 fileds 属性二选一) 模板名由template_name_suffix` 生成:

  • CreateView / UpdateView: /_form.html
  • DeleteView: /_comfirm_delete.html

属性 template_name 可以指定渲染的模板

关联当前登录用户 self.request.user

# models.py
from django.contrib.auth.models import User
from django.db import models

class Author(models.Model):
    name = models.CharField(max_length=200)
    created_by = models.ForeignKey(User, on_delete=models.CASCADE)

from django.views.generic.edit import CreateView
from django.utils.decorators import method_decorator
from myapp.models import Author


@method_decorator(login_reqiured, name='diapatch')
class AuthorCreate(CreateView):
    model = Author
    fields = ['name']

    def form_valid(self, form):
        form.instance.created_by = self.request.user  # 隐式关联当前用户
        return super().form_valid(form)

Ajax

from django.http import JsonResponse
from django.views.generic.edit import CreateView
from myapp.models import Author

class AjaxableResponseMixin:
    """
    Mixin to add AJAX support to a form.
    Must be used with an object-based FormView (e.g. CreateView)
    """
    def form_invalid(self, form):
        response = super().form_invalid(form)
        if self.request.is_ajax():
            return JsonResponse(form.errors, status=400)
        else:
            return response

    def form_valid(self, form):
        # We make sure to call the parent's form_valid() method because
        # it might do some processing (in the case of CreateView, it will
        # call form.save() for example).
        response = super().form_valid(form)
        if self.request.is_ajax():
            data = {
                'pk': self.object.pk,
            }
            return JsonResponse(data)
        else:
            return response

class AuthorCreate(AjaxableResponseMixin, CreateView):
    model = Author
    fields = ['name']

Editing Views

你可能感兴趣的:(Django -- Generic Views - Editing Views)