Как объединить две функции представления с незначительными различиями

Я только что написал две функции представления для двух разных моделей, но они очень похожи и отличаются только некоторыми именами. какой лучший способ объединить эти две функции представления, чтобы предотвратить повторение кода?

вот функции представления:

и другой:

отличия только в именах моделей и адресах шаблонов. а также как я могу переписать их в формате, основанном на классах?

Вы можете создать один общий класс, который наследуется от View Class, а затем два отдельных класса, которые наследуются от предыдущего, например

class ManagerView(View)
  template_name = None
  model = None
  
  def get(self, request):
    ...
    template = loader.get_template(self.template_name)
    approved = self.model.objects.filter(is_approved__exact='0').all()
    ...


class ManagerReligiousView(ManagerView)
  template_name = 'reg/religious-manager-dashboard.html'
  model = ReligiousInfo

class ManagerScientificView(ManagerView)
  template_name ='reg/scientific-manager-dashboard.html'
  model = ScientificInfo
    

Другой способ с представлением на основе класса - использовать редко используемую возможность передавать ему параметры конфигурации в url.

class SomeView( AnyClassBasedView):
    foo = 'bar'

В urls.py

path( '/do_bar/<int:pk>', SomeView.as_view(), name='do_bar'),
path( '/do_baz/<int:pk>', SomeView.as_view( foo='baz'), name='do_baz'),

А в SomeView - условные тесты на self.foo. Обратите внимание, вы должны объявить любой такой параметр со значением по умолчанию в определении класса, прежде чем сможете использовать его в urls.py.

Вариант заключается в использовании написания представления, которое может обрабатывать >1 метод доступа к объекту путем опроса self.kwargs

path( '/x/<int:pk>', X_View.as_view(), name='x_by_pk'),
path( '/x/<str:order_number>', X_View.as_view(), name='x_by_order'),

где обычно метод get_object является подклассом:

class X_View( DetailView):
...

    def get_object( self, queryset=None):
        if 'pk' in self.kwargs:
            obj = get_object_or_404( X, pk=self.kwargs['pk'] )
        elif 'order_number' in self.kwargs:
            obj = get_object_or_404( X, order_number=self.kwargs['order_number'] )
        ...
        else:
            raise ConfigurationError( 'Check urls.py. No valid kwarg was parsed')
        return obj

NB это упрощенный get_object, который игнорирует queryset. См. код get_object для лучшего шаблона, в который можно вставить этот шаблон. Классические CBVs на помощь.

Вернуться на верх