views:

182

answers:

2

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?

+2  A: 

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.

Ignacio Vazquez-Abrams
Thanks, that worked. Is there a straightforward way to find things like that? With a strongly typed language I can very quickly find all methods returning an instance of a particular type and figure things out; in Python I can't really do the same...? Maybe this is just a pathological case, because the content type documentation wasn't linked to from the generic relations docs even though it contains information specific to generic relations, and for some reason I didn't hit that page in my searches...
rabidpebble
This is a hole in Django's documentation (one of many). The relevant parts are all there, but there's nothing that explicitly ties `GenericRelationManager.get_or_create()` to the definition of `ContentType`.
Ignacio Vazquez-Abrams
+2  A: 

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.

Tom
Thanks for these links, they appear to be really helpful. I thinking that part of the problem is just impatience with the learning curve... I'm used to doing things a certain way and I know if I were building this stuff in C# I could get it done in 1/10th the time since I know all the tricks, but I guess I should remember that it took time to get to that point.
rabidpebble
Ha, I just dug into some C#/ Community Server code for the first time in a year or two and sat there trying to figure out how anyone gets anything done if they have to write 10x as much code, so it's all perspective.
Tom
Yup :) I wouldn't be making the effort if I didn't think it would pay off; from my research, it seems clear that Django + Python have a number of advantages over ASP.NET/MVC + C# for the type of work I'm doing at present.
rabidpebble