pythondjangoautocompletedjango-grappelli

Django Grapelli add autocomplete lookups on InlineAdmin


I have this 3 models:

class MyFile(models.Model):
    file = models.FileField(upload_to="files/%Y/%m/%d")

    def __unicode__(self):
        """."""
        return "%s" % (
            self.file.name)    

class ExampleModel(models.Model):
    attached_files =models.ManyToManyField(MyFile)
    main_model = models.ForeignKey(MainModel)    

class MainModel(models.Model):
    attached_files =models.ManyToManyField(MyFile)

And my admin.py as follows:

class ExampleModelAdminInline(admin.TabularInline):
    model = ExampleModel
    extra = 2    

class MainModelAdmin(admin.ModelAdmin):
    inlines = [ExampleModelAdminInline]

Im using django-grapelli because it offer autocomplete lookups for many to many fields. However, Im not sure how to add this autocomplete lookup to a TabularInline admin. Can anyone explain me how to set up the attached_files field to have autocomplete lookups?


Solution

  • First you need to set the static method autocomplete_search_fields() in the Model you want to search from, in your case MyFile. From the docs we get:

    class MyFile(models.Model):
        #your variable declaration...
    
        @staticmethod
        def autocomplete_search_fields():
            return ("id__iexact", "name__icontains",) #the fields you want here
    

    You can also define GRAPPELLI_AUTOCOMPLETE_SEARCH_FIELDS instead of declaring the static method, like:

    GRAPPELLI_AUTOCOMPLETE_SEARCH_FIELDS = {
        "myapp": {
            "MyFile": ("id__iexact", "name__icontains",)
        }
    }
    

    Then you should add the lookup and raw fields to your desired admin class, considering its related Model (say, your ExampleModel) which is the one that has a ManyToManyField. You can also handle ForeignKey in a similar way. Also from the mentioned docs:

    class ExampleModel(models.Model):
        main_model = models.ForeignKey(MainModel) #some FK to other Model related
        attached_files =models.ManyToManyField(MyFile) #the one with static decl      
    
    class MainModelAdmin(admin.ModelAdmin):
        #your variable declaration...
    
        # define raw fields
        raw_id_fields = ('main_model','attached_files',)
        # define the autocomplete_lookup_fields
        autocomplete_lookup_fields = {
            'fk': ['main_model'],
            'm2m': ['attached_files'],
        }
    

    Remember to register both ends (your models) of the relationship to your admin.site, like this:

    #the one with the m2m and the one with the lookup
    admin.site.register(ExampleModel, MainModelAdmin) 
    

    You can also check this question to understand better.