autocomplete_fields with proxy model

Hello,

I’m new to this forum so if I make some mistake or if I posted into the wrong forum or topic please leave me a comment.

My company is currently migrating the Django app from 1.11 to 2.2. Everything was greater until we tried to add automplete_fields to admin.

So our structure is composed of multiple packages that handle a specific domain logic. Example:

  • core -> handles all the models and share logic
  • admin -> handles all admin interfaces

Only core packages are allowed to have models, all other domains extend core models via Django model proxy option.

So the problem occurs when I try to add autocomplete_fields on ModelAdmin which is registered with Proxy model.

Example:

# Company package
class Companies(models.Model):
    name = models.CharField()
    ...

# Customer package
from some.package import Companies

class Customers(models.Model):
    name = models.CharField()
    company = models.OneToOneField(Companies, on_delete=models.CASCADE)

# Admin company package 
# models.py
from some.package import Companies as CoreCompanies

class Companies(CoreCompanies):
    class Meta:
        proxy = True

# admin.py
class CompaniesAdmin(admin.ModelAdmin):
    search_fields = ('id', 'name')

admin.site.register(Companies, CompaniesAdmin)

# Admin customer package
# models.py
from some.other.package import Customers as CoreCustomers

class Customers(CoreCustomers):
    class Meta:
        proxy = True

# admin.py
class CustomersAdmin(admin.ModelAdmin):
    search_fields = ('id', 'name')
    autocomplete_fields = ('company',)

admin.site.register(Customers, CustomersAdmin)

If I enable autocomplete_fields the bottom error is shown in the console:
(admin.E039) An admin for model “Companies” has to be registered to be referenced by CustomersAdmin.autocomplete_fields.

If I register admin without proxy model everything is OK and the apps boots normally.

Thx for the help.

My first impression is that the error message is pretty self-explanatory. Try registering your CompaniesAdmin class.

Sorry, I forgot to include the register line for CompaniesAdmin. We have CompaniesAdmin and CustomersAdmin registered.

The documentation for autocomplete_fields says that it’s used for ForeignKey or ManyToMany fields, it doesn’t say that it’s used for OneToOne fields. (It doesn’t seem like it would be appropriate anyway, since for any Customer there will only be one Company and vice versa. It’s not like there’s anything to choose in that case.)

OK understood. But I thought that autocomplete_fields functionality was made so we don’t have to load all foreign keys to select element (which can kill your browser if you have many results), and for easy foreign key lookup.

I thought as OneToOne field is actually just a ForeignKey with a unique flag turned on, that it will work nonetheless.

But still, your explanation does not explain when Companies model is registered with non-proxy model (original model) everything works fine.

If OneToOne field is really an issue we will have to move to a third party lib.

Can you clarify this please? What specifically did you change between the “working” and “non-working” state?

Nope, that’s my mistake. I mis-read the source code in django.contrib.admin.checks. (This error is being thrown in BaseModelAdminChecks._check_autocomplete_fields_item) A different error that would be generated if that were the problem.

I just registered Companies original model instead if the proxy model.

I changed the code from:

# Companies (proxy model) -> with original Companies model
admin.site.register(Companies, CompaniesAdmin) # Changed only the model

After that everything work fine.

In that case, I’d try creating the proxy with a different name to verify whether or not there’s some “reference confusion” between the base model and proxy model with them both having the same name.

I changed the proxy model class name from Companies to AdminCompaniesModel and the error is still there.

Can you replicate this behavior?