I'm trying to get the user from the request in Django Admin. What I need is access to the request's user in the inline form's clean()
method. I've done a procedure similar to the one described below with a normal ModelForm
(i.e. not an inline one) and I was successful. However, with inlines I'm having a lot of issues.
I have:
class SaleFormset(BaseInlineFormSet):
def __init__(self, *args, **kwargs):
self.request = kwargs.pop('request')
super(SaleFormset, self).__init__(*args, **kwargs)
def _construct_form(self, i, **kwargs):
kwargs['request'] = self.request
super(SaleFormset, self)._construct_form(i, **kwargs)
class SaleProductItemInlineForm(ModelForm):
"""
Custom form for the Sale Product Item Inline used by the
Sale Admin form.
"""
def __init__(self, *args, **kwargs):
self.request = kwargs.pop('request')
super(SaleProductItemInlineForm, self).__init__(*args, **kwargs)
class Meta:
model = SaleProductItem
fields = "__all__"
And in the admin.py, I have:
class SaleProductItemInline(admin.TabularInline):
"""
Tabular inline for a SaleProductItem used in the Sale Admin.
"""
model = models.SaleProductItem
form = SaleProductItemInlineForm
formset = SaleFormset
def get_formset(self, request, obj=None, **kwargs):
formset_class = super(SaleProductItemInline, self).get_formset(request, obj, **kwargs)
class Subset(formset_class):
def __new__(cls, *args, **kwargs):
kwargs['request'] = request
return formset_class(*args, **kwargs)
return Subset
However, I'm getting an error saying that 'NoneType' object has no attribute 'media'
because of this section:
@property
def media(self):
# All the forms on a FormSet are the same, so you only need to
# interrogate the first form for media.
if self.forms:
return self.forms[0].media
django-inline-actions adds actions to each row of the ModelAdmin or InlineModelAdmin.
Inline formsets is a small abstraction layer on top of model formsets. These simplify the case of working with related objects via a foreign key. See examples here: Creating a model and related models with Inline formsets.
You can override forms for django's built-in admin by setting form attribute of ModelAdmin to your own form class. See: https://docs.djangoproject.com/en/dev/ref/contrib/admin/#django.contrib.admin.ModelAdmin.form.
an approach similar to this worked for me:
def SaleProductItemInlineFormFactory(request):
class SaleProductItemInlineForm(ModelForm):
def __init__(self, *args, **kwargs):
# here finally you can do something with your request
super(SaleProductItemInlineForm, self).__init__(*args, **kwargs)
class Meta:
model = SaleProductItem
fields = "__all__"
return SaleProductItemInlineForm
def SaleProductItemInlineFactory(request):
class SaleProductItemInline(admin.TabularInline):
model = models.SaleProductItem
form = SaleProductItemInlineFormFactory(request)
return SaleProductItemInline
class SaleAdmin(admin.ModelAdmin):
inlines = ()
# such way we send request to main form
def get_form(self, request, obj=None, **kwargs):
form = super(SaleAdmin, self).get_form(request, obj=obj, **kwargs)
form.request = request
return form
# we define inlines with factory to create Inline class with request inside
def change_view(self, request, object_id, form_url='', extra_context=None):
self.inlines = (SaleProductItemInlineFactory(request), )
return super(SaleAdmin, self).change_view(request, object_id)
# we define inlines with factory to create Inline class with request inside
def add_view(self, request, form_url='', extra_context=None):
self.inlines = (SaleProductItemInlineFactory(request), )
return super(SaleAdmin, self).add_view(request)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With