Django ReverseSingleRelatedObjectDescriptor.__set__ ValueError

200 views
Skip to first unread message

Bradford Wade

unread,
Mar 18, 2015, 5:07:40 PM3/18/15
to django...@googlegroups.com
I am creating a custom data migration to automatically create GenericRelation entries in the database, based on existing entries across two different models.

Example models.py:

    
  ...
   
class Place
       content_type
= models.ForeignKey(ContentType)
       object_id
= models.PositiveIntegerField()
       content_object
= generic.GenericForeignKey('content_type', 'object_id')




   
class Restaurant
       name
= models.CharField(max_length=60)
       location
= models.CharField(max_length=60)




   
class House
       location
= models.CharField(max_length=60)



Example migration.py:
    
    # -*- coding: utf-8 -*-
   
from django.contrib.contenttypes.models import ContentType
   
from django.db import models, migrations


   
def forwards_func(apps, schema_editor):
       
Restaurant = apps.get_model("simpleapp", "Restaurant")
       
House = apps.get_model("simpleapp", "House")
       
Location = apps.get_model("simpleapp", "Location")


        db_alias
= schema_editor.connection.alias


        content_type
= ContentType.objects.using(db_alias).get(
            app_label
="simpleapp",
            model
="restaurant"
       
)


       
for restaurant in Restaurant.objects.using(db_alias).all():
           
Place.objects.using(db_alias).create(
                content_type
=content_type,
                object_id
=restaurant.id)
       
        content_type
= ContentType.objects.using(db_alias).get(
            app_label
="simpleapp",
            model
="house"
       
)
       
for house in House.objects.using(db_alias).all():
           
Place.objects.using(db_alias).create(
                content_type
=content_type,
                object_id
=house.id)


       
   
class Migration(migrations.Migration):


        dependencies
= [
           
('simpleapp', '0010_location')
       
]


        operations
= [
            migrations
.RunPython(
                forwards_func
,
           
),
       
]




When I run this (Django 1.7.4) I get   

    File ".../django/db/models/fields/related.py", line 597, in __set__
   
self.field.rel.to._meta.object_name,
   
ValueError: Cannot assign "<ContentType: restaurant>": "Place.content_type" must be a "ContentType" instance.


If I comment out the stanza raising the value error the the actual Django model it works as expected. 

Should this exception be raised in the first place? Is this a bug in Django or am I doing it wrong?

Simon Charette

unread,
Mar 18, 2015, 5:33:18 PM3/18/15
to django...@googlegroups.com
Hi Bradford,

You must retrieve the ContentType model from the `apps` instead of importing it just like the other models you're using in your forwards function.

ContentType = apps.get_model("contenttypes", "ContentType")

The reason why you're getting such a strange exception is because you're trying to assign a content type instance from a foreign `apps` instance.

I guess the error message could be improved when the expected model apps doesn't match the assigned one, feel free to open a ticket with this enhancement proposal.

Simon
Reply all
Reply to author
Forward
0 new messages