How do I get the actual object id in a Django admin page (inside formfield_for_foreignkey)?

后端 未结 7 947
爱一瞬间的悲伤
爱一瞬间的悲伤 2020-12-15 09:59

I \'ve already solved the problem of getting the object id being edited using this code:

class CompanyUserInline(admin.StackedInline):
    \"\"\"
    Defines         


        
相关标签:
7条回答
  • 2020-12-15 10:08

    A more general approach could be writing an helper method to obtain the model instance (if any), much as you normally do with a (bounded) ModelForm, and from that retrieve the id or any other property:

    from django.contrib import admin
    
    class MyModelAdmin(admin.ModelAdmin):
    
        def get_instance(self, request):
            try:
                object_id = request.resolver_match.kwargs['object_id']
                obj = self.get_object(request, object_id)
            except:
                obj = None
            return obj
    
    0 讨论(0)
  • 2020-12-15 10:10

    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.

    0 讨论(0)
  • 2020-12-15 10:12

    I made it work by creating a property() in model.py that returns the ID

    models.py:

    class MyModel(models.Model):
        myfield = models.CharField(max_length=75)
        ...
        def get_id(self):
            return str(self.id)
        getid = property(get_id)
    

    admin.py:

    from myapp.models import MyModel
    
    class MyModelAdmin(admin.ModelAdmin):
        list_display = ['mylink',]
        def mylink(self, object):
            return '<a href="http://mywebsite/'+object.getid+'/">Edit</a>'
        mylink.allow_tags = True
    
    admin.site.register(MyModel, MyModelAdmin)
    
    0 讨论(0)
  • 2020-12-15 10:13

    As far as i know it is not possible to access the current instance through the formfield_for_...-methods, because they will only be called for a single field instance!

    A better point to hook into this logic where you can access the whole instance/form would be get_form. You can also overwrite a form field's queryset there!

    0 讨论(0)
  • 2020-12-15 10:15

    I made it work by rewrite change_view()

    class CartAdmin(admin.ModelAdmin):
    
    def change_view(self, request, object_id, form_url='', extra_context=None):
        self.object_id = object_id
        return self.changeform_view(request, object_id, form_url, extra_context)
    
    
    def formfield_for_foreignkey(self, db_field, request, **kwargs):
        print self.object_id
        return super(CartAdmin, self).formfield_for_foreignkey(db_field, request, **kwargs)
    

    then you can call self.object_id inside formfield_for_foreignkey()

    0 讨论(0)
  • 2020-12-15 10:17

    I was dealing with a similar situation, and realized that the id that that I needed from the request, I could from from the model it self since it was a foreign key to that model. So it would be something like:

    cpu = CompanyUser.objects.filter(company__id=self.company_id)
    

    or what ever the structure of your model dictates.

    0 讨论(0)
提交回复
热议问题