基于类的视图的优点是什么?
我今天看到Django 1.3 alpha正在发布,而最受欢迎的新function是引入基于类的视图 。
我已经阅读了相关的文档 ,但是我很难看到使用它们所能获得的巨大优势 ,所以我在这里请求帮助理解它们。
我们来看一个来自文档的高级示例 。
urls.py
from books.views import PublisherBookListView urlpatterns = patterns('', (r'^books/(\w+)/$', PublisherBookListView.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 PublisherBookListView(ListView): context_object_name = "book_list" template_name = "books/books_by_publisher.html", def get_queryset(self): self.publisher = get_object_or_404(Publisher, name__iexact=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(PublisherBookListView, self).get_context_data(**kwargs) # Add in the publisher context['publisher'] = self.publisher return context
现在让我们来比较一下这个问题,我自己在5分钟内做出了一个“简单的旧观点”的解决scheme(我对你可能发现的任何错误表示歉意)。
urls.py
urlpatterns = patterns('books.views', url(r'^books/(\w+)/$', 'publisher_books_list', name="publisher_books_list"), )
views.py
from django.shortcuts import get_object_or_404 from books.models import Book, Publisher def publisher_books_list(request, publisher_name): publisher = get_object_or_404(Publisher, name__iexact=publisher_name) book_list = Book.objects.filter(publisher=publisher) return render_to_response('books/books_by_publisher.html', { "book_list": book_list, "publisher": publisher, }, context_instance=RequestContext(request))
对我来说第二个版本看起来:
- 等同于function
- 更可读(
self.args[0]
?糟糕!) - 短
- 不less于DRY标准
有什么大的我失踪? 我为什么要使用它们? 那些在文档上? 如果是这样,那么理想的用例是什么? mixin有用吗?
提前感谢任何人的贡献!
对于那些可能想知道的人来说,我从来没有被普通的观点所吸引,只要我需要一些先进的function,他们就不会比普通的观点短。
你可以为一个类创build子类,然后像get_context_data一样对特定的情况进行细化,剩下的就是这样。 你不能用函数做到这一点。
例如,您可能需要创build一个新的视图来完成前一个视图的所有操作,但是您需要在上下文中包含额外的variables。 创build原始视图的子类并覆盖get_context_data方法。
另外,将模板渲染成单独的方法所需的步骤可以促进清晰的代码 – 在一个方法中做得越less,就越容易理解。 有了常规的查看function,它们都被转储到一个处理单元中。
如果self.args[0]
困扰你,另一种方法是:
urlpatterns = patterns('books.views', url(r'^books/(?P<slug>\w+)/$', 'publisher_books_list', name="publisher_books_list"), )
然后你可以使用self.kwargs['slug']
来代替它,使它更具可读性。
您的示例函数和类在function上不相同。
基于类的版本免费提供分页,禁止使用GET以外的其他HTTP动词。
如果你想把它添加到你的函数中,将会更长。
但确实更复杂。
这是我听到的第一个 – 我喜欢它。
我在这里看到的优点,诚实地说,它使得视图与Django的整体更加一致。 模型是类,我一直认为,观点也应该是。 我知道不是一切都是,但意见和模型是两种常用的types 。
至于技术优势? 那么,在Python中,一切都是一个类( 或对象 ?) – 那么真的有区别吗? 是不是99%的语法糖呢?
考虑基于类的视图的一种方法是,它们就像是一个Djangopipe理员,具有训练轮子,因此更灵活(但更难以理解)。
例如,pipe理员中的列表显示显然是基于通用的ListView。 最简单的列表视图只能定义模型或查询集。
class MyExampleView(ListView); model = ExampleModel
您将需要提供自己的模板,但基本上与最基本的ModelAdmin相同。 模型admin中的list_display属性将告诉它显示哪些字段,而在ListView中,您将在模板中执行此操作。
class SpeciesAdmin(admin.ModelAdmin): list_display = ['name'] admin.site.register(ExampleModel , ExampleModelAdmin)
与pipe理员你有一个参数
list_per_page = 100
它定义每个页面有多less个对象。 列表视图有
paginate_by = 100
达到同样的目的。 同样,如果你看重pipe理员定制,你会看到很多重叠。
这里的这个网站应该能让你更好的了解他们的工作。
- Djangotesting应用程序错误 – 创buildtesting数据库时出现错误:权限被拒绝创build数据库
- django @login_required装饰器的超级用户
- 如何使Heroku上的Python只有https?
- 在自定义表单中使用Django时间/date小部件
- Django – login后,将用户redirect到他的自定义页面 – > mysite.com/username
- 如何在django上自动创buildcreateuperuser?
- 如何使Django的DateTimeField可选?
- 基于Django类的DeleteView示例
- 在Django中内嵌表单validation