使用super()在基于类的视图中重写get方法

时间:2018-09-05 14:56:28

标签: python django django-class-based-views method-overriding

我创建了一个视图,该视图管理属于当前登录用户的产品(以便当前用户可以观看其自己的产品):

class ProductList(View):
  def get(self, request, *args, **kwargs):
    products = Product.objects.get(user=self.request.user)
    #...

我想从中继承另一个视图,该视图管理属于在url中指定为GET参数的用户的产品(可能与当前用户不同)。是否可以使用super()并覆盖product_list中的方法?像这样:

class ProductListFromUser(ProductList):
   def get(self, request, *args, **kwargs):
     #not sure what code if necessary to put here...
     super().get(self, request, *args, **kwargs): 
     #or here
#...

基本上,我该如何覆盖product_list中的get方法,并通过从URL获取的参数仅更改“ self.request.user”

3 个答案:

答案 0 :(得分:2)

您不应执行任何一项操作。

如果您具有呈现项目列表的视图,则应使用ListView的子类。在该视图中,您可以使用get_queryset方法定义产品列表,可以在两个不同的视图中以相关方式定义产品列表。

class ProductList(ListView):
  def get_queryset(self, *args, **kwargs):
    return Product.objects.filter(user=self.request.user)

class ProductListFromUser(ListView):
  def get_queryset(self, *args, **kwargs):
    return Product.objects.filter(user__username=self.request.GET['user'])

您几乎不需要在基于类的视图中直接定义get(或post)。

答案 1 :(得分:1)

我会将适当的QuerySet的检索移到一个额外的方法上,您可以重写该方法以重用尽可能多的初始代码:

class ProductList(View):

    def get_products(self):
        return Product.objects.all()

    def get(self, request, *args, **kwargs):
        products = self.get_products()
        # ... 

class ProductList(View):

    def get_products(self):
        qs = super().get_products()
        qs = qs.filter(user=self.request.user)
        return qs

    # no get needed

django的ListView及其get_queryset方法附带了此功能。

答案 2 :(得分:0)

如果使用getBqueryset方法(如DetailView所使用的CBV)检索给定请求的查询集,则可以简单地覆盖父类的get_queryset。