【问题标题】:Django: extend get_object for class-based viewsDjango:为基于类的视图扩展 get_object
【发布时间】:2011-10-10 23:23:21
【问题描述】:

作为一名非专业的 Python 程序员,我正在寻找有关我扩展 Django 的 SingleObjectMixin 类的 get_object 方法的反馈。

对于我的大多数 Detail 视图,使用 pk 或 slugfield 进行查找很好 - 但在某些情况下,我需要根据其他(唯一)字段检索对象,例如“用户名”。我继承了 Django 的 DetailView 并修改了 get_object 方法如下:

# extend the method of getting single objects, depending on model
def get_object(self, queryset=None):

    if self.model != mySpecialModel:
        # Call the superclass and do business as usual 
        obj = super(ObjectDetail, self).get_object()
        return obj

    else:
        # add specific field lookups for single objects, i.e. mySpecialModel
        if queryset is None:
            queryset = self.get_queryset()

        username = self.kwargs.get('username', None)
        if username is not None:
            queryset = queryset.filter(user__username=username)
        # If no username defined, it's an error.
        else:
            raise AttributeError(u"This generic detail view %s must be called with "
                                 u"an username for the researcher."
                                 % self.__class__.__name__)

        try:
            obj = queryset.get()
        except ObjectDoesNotExist:
            raise Http404(_(u"No %(verbose_name)s found matching the query") %
                          {'verbose_name': queryset.model._meta.verbose_name})
        return obj

这是好习惯吗?我尝试拥有一个 Detailview 的子类,当要检索不同的对象时,它会根据不同的需求进行调整 - 但它也保持常见情况的默认行为。还是为特殊情况有更多的子类更好?

感谢您的建议!

【问题讨论】:

    标签: django subclassing django-generic-views


    【解决方案1】:

    您可以将DetailView 类上的slug_field 变量设置为应该用于查找的模型字段!在 url 模式中,它始终必须命名为 slug,但您可以将其映射到所需的每个模型字段。

    此外,您还可以覆盖DetailViewget_slug_field 方法,该方法默认只返回self.slug_field

    【讨论】:

    • 谢谢!完全错过了这部分,被get_object中的cmets扔掉了:By default this requires "self.queryset" and a "pk" or "slug" argument in the URLconf, but subclasses can override this to return any object.
    • 每个人都知道基于通用类的视图的文档介于坏与坏之间。
    【解决方案2】:

    你可以使用继承吗?

    class FooDetailView(DetailView):
        doBasicConfiguration
    
    class BarDetailView(FooDetailView):
        def get_object(self, queryset=None):
            doEverythingElse
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-07-29
      • 2013-07-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-05-30
      相关资源
      最近更新 更多