Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

get_or_create generic relations in Django & python debugging in general

I ran the code to create the generically related objects from this demo: http://www.djangoproject.com/documentation/models/generic_relations/

Everything is good intially:

>>> bacon.tags.create(tag="fatty")
<TaggedItem: fatty>
>>> tag, newtag = bacon.tags.get_or_create(tag="fatty")
>>> tag
<TaggedItem: fatty>
>>> newtag
False

But then the use case that I'm interested in for my app:

>>> tag, newtag = bacon.tags.get_or_create(tag="wholesome")
Traceback (most recent call last):
  File "<console>", line 1, in <module>
  File "/usr/local/lib/python2.6/dist-packages/django/db/models/manager.py", line 123, in get_or_create
    return self.get_query_set().get_or_create(**kwargs)
  File "/usr/local/lib/python2.6/dist-packages/django/db/models/query.py", line 343, in get_or_create
    raise e
IntegrityError: app_taggeditem.content_type_id may not be NULL

I tried a bunch of random things after looking at other code:

>>> tag, newtag = bacon.tags.get_or_create(tag="wholesome", content_type=TaggedItem)
ValueError: Cannot assign "<class 'generics.app.models.TaggedItem'>": "TaggedItem.content_type" must be a "ContentType" instance.

or:

>>> tag, newtag = bacon.tags.get_or_create(tag="wholesome", content_type=TaggedItem.content_type)
InterfaceError: Error binding parameter 3 - probably unsupported type.

etc.

I'm sure somebody can give me the correct syntax, but the real problem here is that I have no idea what is going on. I have developed in strongly typed languages for over ten years (x86 assembly, C++ and C#) but am new to Python. I find it really difficult to follow what is going on in Python when things like this break.

In the languages I mentioned previously it's fairly straightforward to figure things like this out -- check the method signature and check your parameters. Looking at the Django documentation for half an hour left me just as lost. Looking at the source for get_or_create(self, **kwargs) didn't help either since there is no method signature and the code appears very generic. A next step would be to debug the method and try to figure out what is happening, but this seems a bit extreme...

I seem to be missing some fundamental operating principle here... what is it? How do I resolve issues like this on my own in the future?

like image 586
rabidpebble Avatar asked Apr 14 '10 23:04

rabidpebble


People also ask

What is generic relations in Django?

Basically it's a built in app that keeps track of models from the installed apps of your Django application.

What is GenericForeignKey Django?

In Django, a GenericForeignKey is a feature that allows a model to be related to any other model in the system, as opposed to a ForeignKey which is related to a specific one. This post is about why GenericForeignKey is usually something you should stay away from.

How do I get content type in Django?

Installing the contenttypes framework The contenttypes framework is included in the default INSTALLED_APPS list created by django-admin startproject , but if you've removed it or if you manually set up your INSTALLED_APPS list, you can enable it by adding 'django. contrib. contenttypes' to your INSTALLED_APPS setting.


2 Answers

ContentType.objects.get_for_model() will give you the appropriate ContentType for a model. Pass the returned object as content_type.

And don't worry too much about "getting it" when it comes to Django. Django is mostly insane to begin with, and experimentation and heavy reading of both documentation and source is encouraged.

like image 165
Ignacio Vazquez-Abrams Avatar answered Nov 01 '22 16:11

Ignacio Vazquez-Abrams


I've collected some Django debugging links here. The two best out of the group are Simon Willison's post (specifically, pdb might make you feel more at home in Python, coming from a C#/ VisualStudio background) and the Django debug toolbar.

like image 35
Tom Avatar answered Nov 01 '22 15:11

Tom