Django: объект запроса доступа от admin form.clean()
Мой вопрос очень похож на этот: Как получить доступ к объекту запроса или любой другой переменной в методе clean() формы?
Кроме того, у меня такая же проблема с формой администратора. Поэтому я не вижу способа самостоятельно инициировать форму, поэтому - передать ей запрос.
Спасибо заранее.
Ответы
Ответ 1
Действительно, есть способ решить вашу проблему!
Вам нужно подклассу, предоставленную ModelAdmin.get_form()
, и переопределить ее:
class BusinessDocumentCommentForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
self.request = kwargs.pop('request', None)
# Voila, now you can access request anywhere in your form methods by using self.request!
super(BusinessDocumentCommentForm, self).__init__(*args, **kwargs)
if self.request.GET.get('document_pk', False):
#Do something
def clean(self):
# Do something with self.request
# etc.
class Meta:
model = BusinessDocumentComment
class BusinessDocumentCommentAdmin(admin.ModelAdmin):
form = BusinessDocumentCommentForm
def get_form(self, request, obj=None, **kwargs):
AdminForm = super(BusinessDocumentCommentAdmin, self).get_form(request, obj, **kwargs)
class AdminFormWithRequest(AdminForm):
def __new__(cls, *args, **kwargs):
kwargs['request'] = request
return AdminForm(*args, **kwargs)
return AdminFormWithRequest
Ответ 2
В классе ModelAdmin
есть несколько крючков, чтобы вы могли это сделать - посмотрите код в django.contrib.admin.options
.
Два метода, которые могут вам помочь, это ModelAdmin.save_form
и ModelAdmin.save_model
, оба из которых передаются объекту запроса. Таким образом, вы можете переопределить эти методы в подклассе Admin и выполнить любую дополнительную обработку.
Отредактировано после комментария
Вы совершенно правы, что это не позволит вам проверить форму, зависящую от пользовательских привилегий. К сожалению, экземпляр формы хранится глубоко внутри методов add_view
и change_view
ModelAdmin
.
Существует не так много возможностей, не дублируя много существующего кода. Вы можете переопределить методы *_view
; или вы можете попробовать и переопределить функцию modelform_factory
, чтобы вернуть новый класс с уже запрограммированным объектом запроса; или вы можете попробовать fiddling с помощью метода класса __new__
сделать то же самое, но это сложно из-за метакласса формы.