django-polymorphic
django-polymorphic copied to clipboard
get_real_instance_class throws TypeError
There is a chance that polymorphic_ctype_id
of an object can point a wrong non-proxy ContentType model. If that case happens polymorphic model's get_real_instance_class throws a TypeError instead of RuntimeError.
issubclass method is called with a None argument like issubclass(model_instance, None)
# Protect against bad imports (dumpdata without --natural) or other
# issues missing with the ContentType models.
if model is not None \
and not issubclass(model, self.__class__) \
and not issubclass(model, self.__class__._meta.proxy_for_model):
raise RuntimeError("ContentType {0} for {1} #{2} does not point to a subclass!".format(
self.polymorphic_ctype_id, model, self.pk,
))
return model
Maybe above code should also check self.__class__._meta.proxy_for_model
is a None or not before calling issubclass?
Hi thanks for reporting this! Could you write a test that replicates this problem? That would help a lot to write a proper solution.
I am experiencing similar problems. While i am able to reproduce in a particular system, i don't know how to re-create this in an encapsulated environment
I found out a descrepency in the polymorphic_ctype_id values in the base class. I still don't know what caused the polymorphic object to point to the wrong CotentType object, but at least it explains why the call fails
I am hitting this too. Have you solved the problem?
Some how for me it appears that the base class is being saved. Then an exception occurs during creating the child. And the base class stays in the database but you can't delete it due to this error. Not sure how this is happening
or perhaps the child class is being deleted and the base class is not. But some how the base class exists without a child references. I am verifying this in the admin using the polymorphic filters
I did find out what my problem was for me, which was unrelated to django-polymorphic directly. I am implementing a multi-tenant system using Postgres schemas. As it turns out, you need to be really careful with content types when doing that. Since django-polymorphic relies on it (polymorphic_ctype_id in the base class) one has to make sure that if multiple schemas do not use the same content-type table, then clearing the content-type cache at every request is important. The only problem related to django-polymorphic was the cryptic error message
Hrm... well I am only using one content type table.
Any idea how to clean up when this happens? It rarely seems to happen but it breaks any code that happens to retrieve one of these records from the database... which is bad on a list view. And I can't seem to delete the records due to the exception
Since I use Postgres i simply used pgAdmin to find the rogue record and modify it. You can easily do a select distinct query on the polymorphic_ctype_id parameter to see if you even have bad records and then another query to see how many of them are. Well, thats what I did in order to fix my records
Sounds simple enough. Thanks for the tip
I've faced with the same exception when I was trying to open admin page for sub-model. After about 1 hour of mindgames I figured out what is the root cause.
My migration was applied incorrectly: parent and sub-entities had same value for the "polymorphic_ctype" and, as result, type of all the sub-entities was recognized as type of parent. That happened because of I copy-pasted migration from here.
The solution is to change forwards_func
source code to handle existing parent-child inheritance relationships as follows:
from django.db import migrations, models
from django.db.models import Q
def forwards_func(apps, schema_editor):
models = apps.get_app_config('projectid').get_models()
content_type = apps.get_model('contenttypes', 'ContentType')
for model in models:
new_ct = content_type.objects.get_for_model(model)
objects = model.objects.filter(
Q(polymorphic_ctype__isnull=True)
| ~Q(polymorphic_ctype=new_ct))
objects.update(polymorphic_ctype=new_ct)
class Migration(migrations.Migration):
.... and etc.
My env:
Django==2.0.4
django-polymorphic==2.0.3
django-rest-polymorphic==0.1.7
I've come across this as well 👍
At first I assumed a version issue between django-polymorphic
, django-filer
, django
.
The polymorphic_ctype_id
for an object in my database links to a content type which isn't a polymorphic (or proxy) model.
This particular project is still in development so databases have been passed between a couple of developers while jobs have been done, so I'm not sure if an object was created in this table, at which point the ctype was a poly/proxy model. Then after that point the databases has been updated by someone else, moved around again & now that ctype isn't a poly model. I suspect this because the newer objects of the same type have a different polymorphic_ctype_id
to that original object.
Surely it makes sense for django-polymorphic
to fail gracefully in this instance. I've got a more explicit solution, so will setup a fork with a PR & some tests.
I ran into this while migrating data from sqlite3 to PostgreSQL. I had to look at the django_content_type
table. I examined the old table and compared it to the new table. It was out of order. Basically I had child models pointing to the wrong content types. So have a look at your django_content_type
table if you are running into this.
We are experiencing the same problem. We use Postgresql Schemas and uses request middleware to switch between different schemas.
Keep in mind that the Model -> Content Type ID links differ from schema to schema due to new models made after the first tenant was created.
class File(PolymorphicModel, mixins.IconsMixin):
When I restart UWSGI and then on Tenant 1 goto the Filer->Folder page in the admin then it works well. Now when I go to Tenant 2 then it seems that django-polymorphic is trying to use the content type id of the File model in Tenant 1 to lookup the real instance class.
Could it be that the ctype_id is being cached somehow?
I'm facing the same issue when calling a polymorphic class has anyone found a solution