Django error with sites package: "The model Site is already registered in app 'sites'"

Viewed 1177

I am trying to install the sites package and upon running makemigrations am receiving the error:

django.contrib.admin.sites.AlreadyRegistered: The model Site is already registered in app 'sites'.

This is my admin.py:

from django.contrib import admin

# Register your models here.
from django.apps import apps

models = apps.get_models()

for model in models:
    try:
        admin.site.register(model)
    except admin.sites.AlreadyRegistered:
        pass

And here are my installed apps:

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'webpage',
    'django_user_agents',
    'analytical',
    'corsheaders',
    'django.contrib.sites',
]

Any idea what might be causing this issue? Please let me know if there is information missing.

2 Answers

You are registering all models of all apps in your admin.py. You seem to be aware of the fact that some model may already be registered and use a try-except block to catch that. But the problem is that other packages don't know that you are doing this and obviously won't use try-except blocks. You get the error because you successfully register the model Site with the admin site but then when django.contrib.sites tries to register the same it fails since it is already registered.

One solution may to be order your INSTALLED_APPS better and your apps be last. Currently you have django.contrib.sites listed after many apps (even third party ones):

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'django.contrib.sites', # Move it here
    'webpage',
    'django_user_agents',
    'analytical',
    'corsheaders',
]

Again this might cause errors if some other apps try to register their models. Instead of doing this brute force registering of all models consider registering the models for only your app inside it's admin.py:

from django.contrib import admin

# Register your models here.
from django.apps import apps

app_config = apps.get_app_config('your_app_name') # Replace your_app_name it is just a placeholder
models = app_config.get_models()

for model in models:
    try:
        admin.site.register(model)
    except admin.sites.AlreadyRegistered:
        pass

Your admin registered the models of sites app before sites app, the best solution is to skip the sites model in your admin so the admin in sites can register its models.

Related