I 've already solved the problem of getting the object id being edited using this code:
class CompanyUserInline(admin.StackedInline):
"""
Defines tabular rules for editing company users direct in company admin
"""
model = CompanyUser
def formfield_for_foreignkey(self, db_field, request, **kwargs):
if db_field.name == "user":
users = User.objects.filter( Q(is_superuser=False) )
query = Q()
for u in users:
aux = CompanyUser.objects.filter(user=u)
if aux.count() == 0:
query |= Q(pk=u.id)
try:
cpu = CompanyUser.objects.filter(company__id=int(request.path.split('/')[4]))
for p in cpu:
query |= Q(pk=p.user.id)
except:
pass
kwargs["queryset"] = User.objects.filter(query).order_by('username')
return super(CompanyUserInline, self).formfield_for_foreignkey(db_field, request, **kwargs)
But, the int(request.path.split('/')[4]) is really ugly. I want to know how I get the id from the Django AdminModel. I'm sure it's somewhere inside it, anyone knows?
Thank you in advance! ;D
One way to show the ID field is to make it editable by removing editable=False from the model definition.
Overview. The Django admin application can use your models to automatically build a site area that you can use to create, view, update, and delete records. This can save you a lot of time during development, making it very easy to test your models and get a feel for whether you have the right data.
After some digging around, we were able to grab the arguments that get passed to the admin view (after being parsed by django admin's urls.py) and use that (self_pub_id) to grab the object:
class PublicationAdmin(admin.ModelAdmin):
def formfield_for_manytomany(self, db_field, request, **kwargs):
if db_field.name == "authors":
#this line below got the proper primary key for our object of interest
self_pub_id = request.resolver_match.args[0]
#then we did some stuff you don't care about
pub = Publication.objects.get(id=self_pub_id)
kwargs["queryset"] = pub.authors.all()
return super(PublicationAdmin, self).formfield_for_manytomany(db_field, request, **kwargs)
A more elegant solution is to use the accepted answers recomendation and leverage the get_form ModelAdmin member function. Like so:
class ProfileAdmin(admin.ModelAdmin):
my_id_for_formfield = None
def get_form(self, request, obj=None, **kwargs):
if obj:
self.my_id_for_formfield = obj.id
return super(ProfileAdmin, self).get_form(request, obj, **kwargs)
def formfield_for_foreignkey(self, db_field, request, **kwargs):
if db_field.name == "person":
kwargs["queryset"] = Person.objects.filter(profile=self.my_id_for_formfield)
return super(ProfileAdmin, self).formfield_for_foreignkey(db_field, request, **kwargs)
The following code snippet will give you the object id:
request.resolver_match.kwargs['object_id']
Sample usage: (I'm filtering the phone numbers shown, to only show customer's phone numbers)
def formfield_for_foreignkey(self, db_field, request, **kwargs):
if db_field.name == 'preferred_contact_number':
kwargs['queryset'] = CustomerPhone.objects.filter(customer__pk=request.resolver_match.kwargs['object_id'])
return super().formfield_for_foreignkey(db_field, request, **kwargs)
P.S: Found it by debugging and walking through accessible variables.
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