django中通用视图优点,基本用法以及获取url参数的方法

经常碰到这种情况,需要调用某个模板,但可能存在不同的逻辑条件。如果为每个不同的逻辑条件都写个视图,则每个视图里都要单独指定模板文件并进行渲染,造成代码冗余。

因此可以引入通用视图,ListViewDetailView,这两个视图分别抽象“显示一个对象列表”和“显示一个特定类型对象的详细信息页面”这两种概念。

使用通用视图优点:实现视图中最基本的模板调用和渲染功能,并可以加入通用的逻辑条件。在遇到需要使用其他逻辑条件的情况,可以新建一个类并继承该通用视图,在新类里重写逻辑条件,而无需再次指定和渲染模板,减少代码冗余。

ListView

ListView用来获取指定的数据列表

下面建立了一个通用视图BookListView,用来显示已上架的图书列表,请注意:

  1. urls.py中调用的是as_view()方法
  2. 默认模板为/_list.html,使用template_name来指定模板文件
  3. 查询获得的数据,传递给模板时所使用的变量名默认格式是_list,使用context_object_name可以指定变量名
# books/views.py
from django.views.generic import ListView
from .models import Book

class BookListView(ListView):
    # 指定模型
    model = Book
    # 指定模板
    template_name = 'books/book_list.html'
    # 从模型中查询获得的数据,传递给模板时所使用的变量名
    context_object_name = 'book_list'
    # 添加逻辑条件
    def get_queryset(self):
        return Book.objects.filter(status='已上架')
    
    
# books/urls.py
from django.urls import path
from . import views

urlpatterns = [
    path('book_list', views.BookListView.as_view())
]

若现在又有新的需求,要根据书名、作者或出版社来筛选图书,则可以建立个新类继承BookListView,重写逻辑条件,而无需重复指定模板。将来在显示图书列表时如有其他新的需求,同样如下操作,只需重写逻辑条件即可。

# books/views.py
class BookListView(ListView):
    pass

class FilterBookListView(BookListView):
    def get_queryset(self):
        item_dict = {
     
            'book': 'title',
            'author': 'authors__name',
            'publisher': 'publisher__name'
        }
        return Book.objects.filter(
            **{
     item_dict[self.kwargs['item']]: self.kwargs['data']})
    
    
# books/urls.py
urlpatterns = [
    path('book_list', views.BookListView.as_view()),
    path('book_list//', views.FilterBookListView.as_view()),
]

关于url传参: 这里的参数是写在URLconf里的,可以使用self.kwargs[]来获取参数,如果是使用URL参数来传递,可以使用self.request.GET.dict()获取。

DetailView

DetailView用来获取指定的单条数据

使用方法与ListView类似,但注意几点:

  1. DetailView是根据模型中的主键进行数据选取,默认期望从URL中获取名为pk的主键值,因此URLconf里关于主键的格式应为,也可以使用pk_url_kwarg来指定主键名
  2. 查询获得的数据,传给模板时所使用的变量名默认就是模型名,可以使用context_object_name来指定变量名
# books/views.py
from django.views.generic import DetailView
class BookDetailView(DetailView):
    model = Book
    template_name = 'books/book_info.html'
    # 指定主键名
    pk_url_kwarg = 'id'
    
    
# books/urls.py
urlpatterns = [
    path('book_info/', views.BookDetailView.as_view())
]

上面并未指定context_object_name,因此在模板中使用默认变量名也就是模型名{ { book }}来访问传入的数据

你可能感兴趣的:(django,技巧,django,python)