If you proxy a model that is already a proxy, it will be of the same type as the first proxy. If the second proxy is used in a foreign key, you will not be able to create any model objects which have a value for that foreign key because they will fail the type check validation.
This means we can only ever proxy actual models, and cannot create a base proxy model to subclass as necessary.
# models.
from django.contrib.auth import models as auth_models
from django.db import models
class User1(auth_models.User):
class Meta:
proxy = True
class User2(User1):
class Meta:
proxy = True
class Something(models.Model):
user = models.ForeignKey(User2)
# interactive shell.
>>> from myapp.models import User1, User2, Something
>>> type(User1.objects.get(username='admin'))
<class 'myapp.models.User1'>
>>> type(User2.objects.get(username='admin'))
<class 'myapp.models.User1'>
>>> Something.objects.create(user=User2.objects.get(username='admin'))
Traceback (most recent call last):
File "<console>", line 1, in ?
File "/path/to/django/db/models/manager.py", line 126, in create
return self.get_query_set().create(**kwargs)
File "/path/to/django/db/models/query.py", line 283, in create
obj = self.model(**kwargs)
File "/path/to/django/db/models/base.py", line 308, in __init__
setattr(self, field.name, rel_obj)
File "/path/to/django/db/models/fields/related.py", line 270, in __set__
raise ValueError('Cannot assign "%r": "%s.%s" must be a "%s" instance.' %
ValueError: Cannot assign "<User1: admin>": "Something.user" must be a "User2" instance.
Looks like the incorrect model is being assigned to the manager (or simply being copied unchanged from the base proxy class). This causes any querysets from the manager to create model objects of the wrong type.