50👍
Indeed, there is a way to solve your issue!
You will need to subclass form provided by ModelAdmin.get_form()
and override it:
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👍
This solution works for me. You can use self.request
anywhere in the form to use it, including def clean(self)
class MyModelAdmin(admin.ModelAdmin):
form = MyForm
def get_form(self, request, *args, **kwargs):
form = super(MyModelAdmin, self).get_form(request, *args, **kwargs)
form.request = request
return form
- Django string concatenation inside template tag best practice
- Add extra field to ModelForm
- Django 1.9 JSONField order_by
1👍
There are a number of hooks in the ModelAdmin
class to allow you to do things this – look at the code in django.contrib.admin.options
.
Two methods that might help you are ModelAdmin.save_form
and ModelAdmin.save_model
, both of which are passed the request object. So you can override these methods in your Admin subclass and do any extra processing you need.
Edited after comment
You’re quite right that this won’t let you validate the form dependent on the user’s privileges. Unfortunately the form instantiation is buried deep within the add_view
and change_view
methods of ModelAdmin
.
There aren’t many possibilities without duplicating a lot of existing code. You could override the *_view
methods; or you could try and override the modelform_factory
function to return a new class with the request object baked in already; or you could try fiddling with the form class __new__
method to do the same thing, but that’s tricky because of the form metaclass.
- In django, is there a way to directly annotate a query with a related object in single query?
- Saving a Pandas DataFrame to a Django Model