Чистый способ настройки форм на основе группы пользователей в Django

Я хочу настроить формы моей модели на основе группы пользователей. Настройки, о которых я говорю, небольшие, но чтобы дать вам представление, мои "настройки" будут примерно такими :

  • пользователи в GroupA будут иметь BooleanField с True по умолчанию, даже если по умолчанию False для других
  • .
  • пользователи в GroupB будут иметь CharField (вводимый текст) скрытым (не изменяемым)
  • пользователи в группеС будут иметь не те же опции, что и другие для CharField с опциями (различные опции в select)
  • .
  • ...

В настоящее время я фактически добился этого, выполняя смесь логики в моем views.py и в моем forms.py.

Но мне не очень нравится смешивать логику в 2 разных файлах, поэтому я пришел спросить ваше мнение о том, какой способ является лучшим (наиболее чистым) на ваш взгляд и как его достичь.

Вот 2 техники, о которых я думаю:

1. Создание формы для каждой группы в forms.py.

Это был бы самый чистый способ.
Создавая форму для каждой группы (MyModelGroupAForm(ModelForm), MyModelGroupBForm(ModelForm), ...) я могу легко изменить поле/вход/... в моем forms.py файле каждый раз, когда запрашивается изменение и/или создается группа.
Затем, все, что мне нужно сделать, это переопределить метод get_form(self) в моих MyModelCreateView и MyModelUpdateView, и изменить self.form_class на правильную форму, основанную на группе пользователя, как показано ниже:

Class MyModelCreateView(CreateView):
    model = MyModel
    form_class = MyModelDefaultForm
    
    def get_form(self):
        if self.request.user.groups.filter(name='GroupA').exists():
            self.form_class = MyModelGroupAForm
        elif self.request.user.groups.filter(name='GroupB').exists():
            self.form_class = MyModelGroupBForm
        elif ...  # another group
        
        form = super().get_form()
        return form
    
    ...

Недостатком этой техники является то, что мне придется сделать много форм с одинаковыми данными: например, одно из моих полей запрашивает виджет. Это означает, что КАЖДАЯ форма, которую я создаю для КАЖДОЙ группы, должна будет указывать my_field = forms.CharField(widget=DatePickerInput()), так как указать виджет в определении модели в models.py невозможно. Это кажется не совсем DRY... (есть ли какое-то наследование между формами? Если бы я мог заставить форму наследоваться от абстрактной формы, мне бы не пришлось каждый раз определять поле)

2. Обработка всей логики в файле views.py.

Это делает мой views.py файл очень длинным...
В принципе, в классе MyModelCreateView в моем views.py я бы изменил поле в методе get_form() на основе группы self.request.user. И там я бы реализовал много логики типа if/else/switch, основанной на группе и изменении каждого поля, как показано ниже:

Class MyModelCreateView(CreateView):
    model = MyModel
    form_class = MyModelDefaultForm
    
    def get_form(self):
    
        form = super().get_form()

        if self.request.user.groups.filter(name='GroupA').exists():
            # change the default of a boolean field to True, instead of False
            # another change specific to group A making the method even longer
            # ...
        elif self.request.user.groups.filter(name='GroupB').exists():
            # hide/remove a CharField
            # another change specific to group B making the method even longer
            # ...
        elif ... # another group

        return form

Имо, это не очень чисто. Пока у меня меньше 10 групп, так что все в порядке. Но позже у меня будет гораздо больше групп, что означает, что моя логика if/elif/elif/... будет огромной... Кроме того, мне нужно будет скопировать эту логику в MyModelUpdateView также в
... Не совсем DRY...

Что вы думаете? Какой самый лучший/чистый способ сделать это?

(На данный момент я делаю смесь из technic 1 и technic 2)

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