Wednesday, March 18, 2015

Re: Django ReverseSingleRelatedObjectDescriptor.__set__ ValueError

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

Le mercredi 18 mars 2015 17:07:40 UTC-4, Bradford Wade a écrit :
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?

--
You received this message because you are subscribed to the Google Groups "Django users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to django-users+unsubscribe@googlegroups.com.
To post to this group, send email to django-users@googlegroups.com.
Visit this group at http://groups.google.com/group/django-users.
To view this discussion on the web visit https://groups.google.com/d/msgid/django-users/8934dee7-325e-43a5-992d-e317f0adb980%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

No comments:

Post a Comment