Django: расширить get_object для представлений на основе классов

Будучи неопытным программистом на Python, я ищу отзывы о том, как я расширил метод get_object класса SingleObjectMixin Django.

Для большинства моих представлений 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, который приспосабливается к различным потребностям, когда нужно получить разные объекты, но который также поддерживает поведение по умолчанию для общих случаев. Или лучше иметь больше подклассов для особых случаев?

Спасибо за совет!


person Gregor    schedule 22.07.2011    source источник


Ответы (2)


Вы можете установить переменную slug_field в классе DetailView в поле модели, которое должно использоваться для поиска! В шаблонах URL он всегда должен называться slug, но вы можете сопоставить его с любым полем модели, которое хотите.

Кроме того, вы также можете переопределить метод get_slug_field DetailView, который возвращает только self.slug_field по умолчанию!

person Bernhard Vallant    schedule 22.07.2011
comment
Спасибо! Полностью пропустил эту часть, был отброшен комментариями в get_object: By default this requires "self.queryset" and a "pk" or "slug" argument in the URLconf, but subclasses can override this to return any object. - person Gregor; 22.07.2011
comment
Как всем известно, документация по представлениям на основе общих классов находится где-то между плохим и злым. - person Bernhard Vallant; 22.07.2011

Можно ли использовать наследование?

class FooDetailView(DetailView):
    doBasicConfiguration

class BarDetailView(FooDetailView):
    def get_object(self, queryset=None):
        doEverythingElse
person AA.    schedule 22.12.2011