Django изменяет поля FormView перед проверкой формы

Есть ли правильный способ изменить поля формы перед проверкой данных на основе классов FormView. Точнее CreateView. Необходимо использовать представления на основе классов, потому что я добавляю кучу пользовательских миксинов:

class Create(HtmxRequiredMixin, CreatedByMixin, HxFormValidationMixin, BaseMixin, CreateView):
    template_name = 'administration/form.html'
    model = Object
    form_class = Form
    success_url = reverse_lazy('object-list')
    hx_retarget = '#CREATE'
    base = 'object'
    views_list = ('create',)

Я использовал CreatedByMixin в наборе представлений DRF для остального API. это выглядит как:

class CreatedByMixin:
    def create(self, request, *args, **kwargs):
        data = request.data.copy()
        if request.user.is_authenticated:
            data['created_by'] = request.user.id
        serializer = self.get_serializer(data=data)
        serializer.is_valid(raise_exception=True)
        self.perform_create(serializer)
        headers = self.get_success_headers(serializer.data)
        return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers)

Мне нужен аналогичный миксин для моего CreateView, но я не уверен, какой метод лучше всего переопределить.

Кроме того, HxFormValidationMixin уже переопределяет методы form_valid и form_invalid.

Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
0
55
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

FormView наследует от FormMixin, который реализует метод get_form_kwargs(). Переопределив этот метод, вы можете испортить kwarg data до того, как он будет передан конструктору формы.

def get_form_kwargs(self):
    kwargs = super().get_form_kwargs()

    if 'data' in kwargs:
       data = kwargs['data'].copy()

       # change whatever you want
       data['foo'] = 'bar'

       # replace the original with the copy
       kwargs['data'] = data

    return kwargs

Это работает и в других случаях, но как мне получить доступ к запросу отсюда? Нет ли в конвейере другого переопределяемого метода с доступом к запросу?

42WaysToAnswerThat 03.07.2024 04:54

@ 42WaysToAnswerЧто я обновлю ответ, который он покажет, когда он будет одобрен, вот как вы можете получить доступ к запросу.

Tanveer 03.07.2024 09:17

@Tanveer, я не вижу никаких изменений или уведомлений о редактировании. Возможно, ваше изменение не было зафиксировано.

42WaysToAnswerThat 03.07.2024 09:20

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

Tanveer 03.07.2024 09:21

@Танвир, да, добавь свой ответ, пожалуйста

42WaysToAnswerThat 03.07.2024 10:40

посмотрите, пожалуйста, я только что добавил

Tanveer 03.07.2024 10:49

Вы также можете получить доступ к self.request из этого метода. Но не обязательно делать то, что вы хотите. Смотрите мой комментарий к другому ответу.

little_birdie 03.07.2024 18:50

На самом деле, если вы действительно хотите перехватить объект запроса до того, как что-либо в вашем представлении его использует, вам следует переопределить метод dispatch. Но если все, что вам нужно, это изменить данные сообщения формы, вы можете сделать это, как я вам показал, переопределив get_form_kwargs.. это гораздо более конкретное решение, поэтому вероятность поломки меньше.

little_birdie 03.07.2024 21:02
Ответ принят как подходящий

Фактическая реализация def get_form_kwargs(self): в FormMixin, которая наследуется от ContextMixin. вы можете получить доступ к запросу, используя self.request, а когда у вас есть self.request, вы можете делать все, что захотите.

def get_form_kwargs(self,*args,**kwargs):
    kwargs = super().get_form_kwargs(*args,**kwargs)

    if self.request.method in ("POST", "PUT"):
        data = kwargs['data'].copy()
        #modify data here
        kwargs['data'] = data

    return kwargs 

Это всего лишь копия кода, взятого непосредственно из Django FormMixin. Проблема с этим способом заключается в том, что вы предотвращаете вызов исходного FormMixin. Теперь, если в будущем обновлении Django к FormMixin.get_form_kwargs() будет добавлен дополнительный код, он не будет выполнен. Почти всегда лучше при программировании вызвать метод суперкласса, а затем просто изменить именно то поведение, которое вам нужно изменить, а не переопределять поведение, которое вам не нужно менять.

little_birdie 03.07.2024 18:49

@little_birdie согласилась

Tanveer 04.07.2024 09:47

@little_birdie, поэтому я исправил, чтобы сначала вызывался супер.

42WaysToAnswerThat 05.07.2024 19:36

да, вы правы, спасибо.

Tanveer 06.07.2024 09:34

Хорошо, теперь вы буквально скопировали мой ответ, невероятно.

little_birdie 08.07.2024 17:18

Проверьте разницу между вашим и моим, мы здесь, чтобы дать ответ. не для насмешки.

Tanveer 09.07.2024 10:28

Другие вопросы по теме