Есть ли правильный способ изменить поля формы перед проверкой данных на основе классов 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
.
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
@ 42WaysToAnswerЧто я обновлю ответ, который он покажет, когда он будет одобрен, вот как вы можете получить доступ к запросу.
@Tanveer, я не вижу никаких изменений или уведомлений о редактировании. Возможно, ваше изменение не было зафиксировано.
он находится на рассмотрении, когда он будет одобрен, он покажет вам. или я тоже могу добавить свой ответ?
@Танвир, да, добавь свой ответ, пожалуйста
посмотрите, пожалуйста, я только что добавил
Вы также можете получить доступ к self.request из этого метода. Но не обязательно делать то, что вы хотите. Смотрите мой комментарий к другому ответу.
На самом деле, если вы действительно хотите перехватить объект запроса до того, как что-либо в вашем представлении его использует, вам следует переопределить метод dispatch
. Но если все, что вам нужно, это изменить данные сообщения формы, вы можете сделать это, как я вам показал, переопределив get_form_kwargs
.. это гораздо более конкретное решение, поэтому вероятность поломки меньше.
Фактическая реализация 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 согласилась
@little_birdie, поэтому я исправил, чтобы сначала вызывался супер.
да, вы правы, спасибо.
Хорошо, теперь вы буквально скопировали мой ответ, невероятно.
Проверьте разницу между вашим и моим, мы здесь, чтобы дать ответ. не для насмешки.
Это работает и в других случаях, но как мне получить доступ к запросу отсюда? Нет ли в конвейере другого переопределяемого метода с доступом к запросу?