美文网首页
Views#3-通过类编写的视图函数

Views#3-通过类编写的视图函数

作者: wangfp | 来源:发表于2017-09-20 12:25 被阅读0次

Class-based views

官方推荐使用通用视图类

  • 简单示例
    # models.py
    from django.db import models
    
    class Publisher(models.Model):
        name = models.CharField(max_length=30)
        address = models.CharField(max_length=50)
        city = models.CharField(max_length=60)
        state_province = models.CharField(max_length=30)
        country = models.CharField(max_length=50)
        website = models.URLField()
    
        class Meta:
            ordering = ["-name"]
    
        def __str__(self):              # __unicode__ on Python 2
            return self.name
    
    # views.py
    from django.views.generic import ListView
    from books.models import Publisher
    
    class PublisherList(ListView):
        # model类属性指定了使用的数据模型
        model = Publisher
        # 如不指定template_name属性,Django会自动为该类指定一个模板路径(比方该类的默认路径为"books/publisher_list.html",books是app名称)
        # 同时会自动将查找的结果指向'object_list'变量,从而可以在模板中直接使用
    
    # urls.py
    from django.conf.urls import url
    from books.views import PublisherList
    
    urlpatterns = [
        # PublisherList并不是视图函数,因此不能直接调用,而需要调用as_view()类方法
        url(r'^publishers/$', PublisherList.as_view()),
    ]
    

  • 指定模板使用的环境变量名
    class PublisherList(ListView):
        model = Publisher
        # 通过context_object_name类属性来指定
        context_object_name = 'my_favorite_publishers'
    
  • 添加额外的环境变量
    重载get_context_data()方法
    from django.views.generic import DetailView
    from books.models import Publisher, Book
    
    class PublisherDetail(DetailView):
    
        model = Publisher
    
        def get_context_data(self, **kwargs):
            # Call the base implementation first to get a context
            context = super(PublisherDetail, self).get_context_data(**kwargs)
            # Add in a QuerySet of all the books
            context['book_list'] = Book.objects.all()
            # 最终返回context
            return context
    

  • 指定视图类使用的对象
    除了使用model属性外,通过queryset属性也可以指定视图类处理的对象

    from django.views.generic import ListView
    from books.models import Book
    
    class BookList(ListView):
        # 该视图类处理的对象由queryset指定,这样做的好处是可以更明确地处理返回结果
        queryset = Book.objects.order_by('-publication_date')
        context_object_name = 'book_list'
    
  • 自动筛选对象
    如果通过model或者queryset来指定查找对象,面对不同的筛选条件,需要定义不同的视图类,这样做就会显得很繁琐
    Django提供了get_queryset()方法来处理不同的筛选条件

    当调用视图类时,绝大多数的信息将保存在self中(如self.request);其中self.args将保存URLconf传入的位置参数,self.kwargs将保存URLconf传入的关键字参数

    # urls.py
    urlpatterns = [
        # 正则表达式中有一个位置参数,将保存到其调用的视图类(PublisherBookList)的self.args中
        url(r'^books/([\w-]+)/$', PublisherBookList.as_view()),
    ]
    
    # views.py
    from django.shortcuts import get_object_or_404
    from django.views.generic import ListView
    from books.models import Book, Publisher
    
    class PublisherBookList(ListView):
    
        template_name = 'books/books_by_publisher.html'
    
        # 该方法返回视图类的处理对象
        def get_queryset(self):
            # 此处用self的publisher属性指向所得结果是为了在后续方法中也可以使用该对象
            # self.args保存的是位置参数列表
            self.publisher = get_object_or_404(Publisher, name=self.args[0])
            return Book.objects.filter(publisher=self.publisher)
    
        # 该方法添加环境变量
        def get_context_data(self, **kwargs):
            # Call the base implementation first to get a context
            context = super(PublisherBookList, self).get_context_data(**kwargs)
            # Add in the publisher
            # 此处就使用到了上文中定义的self.publisher对象
            context['publisher'] = self.publisher
            return context
    

  • 对象预处理/善后
    get_object()方法可以获得将要处理的对象,通过对该方法的重载,可以对对象进行一些额外的处理
    # urls.py
      urlpatterns = [
        # 对于DetailView的视图类,需要通过pk关键字参数(django默认为pk,也可以指定为其它)来指定所需的对象
        url(r'^authors/(?P<pk>[0-9]+)/$', AuthorDetailView.as_view(), name='author-detail'),
    ]
    
    # views.py
    from django.views.generic import DetailView
    from django.utils import timezone
    from books.models import Author
    
    class AuthorDetailView(DetailView):
    
        # 指定处理对象(实质上是model=Author的另一种表现)
        queryset = Author.objects.all()
    
        # 该方法可用于对对象属性的一些处理
        def get_object(self):
            # Call the superclass
            object = super(AuthorDetailView, self).get_object()
            # Record the last accessed date
            object.last_accessed = timezone.now()
            object.save()
            # 最终需要返回对象本身
            return object
    

  • 通用编辑视图
    主要用于表单视图
    • FormView
    • CreateView
    • UpdateView
    • DeleteView
      主要通过视图类来处理表单
  • 基础表单
    # forms.py
    from django import forms
    
    class ContactForm(forms.Form):
        name = forms.CharField()
        message = forms.CharField(widget=forms.Textarea)
    
        def send_eamil(self):
            # send email using the self.cleaned_data dictionary
            pass
    
    对于上述表单可以通过FormView来创建视图
    # views.py
    from myapp.forms import ContactForm
    from django.views.generic.edit import FormView
    
    class ContactView(FormView):
        template_name = 'contact.html'
        # form_class指定自定义的表单
        # 也可以通过指定model、queryset属性或者重载get_object()方法来使用Django自动生成的表单
        form_class = ContactForm
        # 若表单提交成功,将会转向success_url页面
        success_url = '/thanks/'
    
        # 该方法用于自动提交合理表单(可以重载)
        def form_valid(self, form):
            # This method is called when valid form data has been POSTed.
            # It should return an HttpResponse.
            form.send_email()
            return super(ContactView, self).form_valid(form)
    
    对于实现了get_absolute_url()方法的数据模型,CreateView或者UpdateView视图函数都无需指定success_url属性
    # 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
    
    # AuthorCreate和AuthorUpdate表单在成功提交会,会自动转向get_absolute_url()方法返回的页面
    class AuthorCreate(CreateView):
        model = Author
        # fields的用法和ModelForm的Meta类中定义的fields属性一致;
        # 若ModelForm中没有定义fields属性(即自动生成ModelForm时),则需要在Generic editing views中显示指定
        # 因此,若在同一个视图类中同时指定fields和form_class属性,会引发ImproperlyConfigured异常
        fields = ['name']
        # 可以通过指定template_name属性来设置使用的模板
        # 此处并未指定,因此AuthorCreate和AuthorUpdate类默认使用myapp/author_form.html
        # AuthorDelete类会默认使用myapp/author_confirm_delete.html
    
    class AuthorUpdate(UpdateView):
        model = Author
        fields = ['name']
    
    class AuthorDelete(DeleteView):
        model = Author
        success_url = reverse_lazy('author-list')
    
    # urls.py
    urlpatterns = [
        # URLconf的设置同DetailView一致,需要传入pk关键字参数指定使用的具体数据
        url(r'author/add/$', AuthorCreate.as_view(), name='author-add'),
        url(r'author/(?P<pk>[0-9]+)/$', AuthorUpdate.as_view(), name='author-update'),
        url(r'author/(?P<pk>[0-9]+)/delete/$', AuthorDelete.as_view(), name='author-delete'),
    ]
    

相关文章

  • Views#3-通过类编写的视图函数

    Class-based views 官方推荐使用通用视图类 简单示例# models.pyfrom django....

  • rest_framework 通用视图

    通过继承rest_framework的APIView,我们可以完成视图类的编写,在大多视图类的编写中,我们的行为是...

  • Tutorial 3: Class-based Views

    Tutorial 3: Class-based Views 我们还可以使用基于类的视图而不是基于函数的视图来编写A...

  • Django重温2

    1 ..类视图 1.1 类视图引入 以函数的方式定义的视图称为函数视图,函数视图便于理解。但是遇到一个视图对应的路...

  • 基于类的视图

    我们也可以使用基于类的视图编写我们的 API 视图,而不是基于函数的视图。我们将看到这是一个强大的模式,允许我们重...

  • Flask系列教程(16)——类视图

    类视图 之前我们接触的视图都是函数,所以一般简称视图函数。其实视图也可以基于类来实现,类视图的好处是支持继承,但是...

  • 1.6 flask 类视图

    类视图 之前我们接触的视图都是函数,所以一般简称视图函数。其实视图也可以基于类来实现,类视图的好处是支持继承,但是...

  • 类视图

    之前我们接触的视图都是函数,所以一般简称视图函数。其实视图也可以基于类来实现,类视图的好处是支持继承,但是类视图不...

  • Django Restful Framework基于类的视图

    我们还可以使用基于类的视图而不是基于函数的视图来编写API视图。我们将看到这是一个强大的模式,允许我们重用常用的功...

  • 5.Django视图系统

    Django视图系统 Django的View一个视图函数(类),简称视图,是一个简单的Python 函数(类),它...

网友评论

      本文标题:Views#3-通过类编写的视图函数

      本文链接:https://www.haomeiwen.com/subject/xngnsxtx.html