views:

183

answers:

2

I have a question about django content_types

In the example of filtering a QuerySet for a generic content type on http://www.djangoproject.com/documentation/models/generic_relations/ there are the following lines.

ctype = ContentType.objects.get_for_model(quartz)
TaggedItem.objects.filter(content_type__pk=ctype.id, object_id=quartz.id)

Can anyone explain what content_type__pk means?

Does the __ mean that there's an indirection going on? What does that mean in the context of the left-hand side of a match in the filter?

I see that in the model definition

content_type = models.ForeignKey(ContentType)

but when translated into the database there is no field called content_type, but there is a content_type_id ... so is it that content_type__pk actually translates into content_type_id? And if so, why didn't they use this in the filter example?

+1  A: 

No, it is the TaggedItem model that has a field of type ContentType, which is called content_type.

Each model has a primary key to which you refer by "pk". Most of the time it IS the "id" field. But sometimes it is not.

In order to be consistent about it you can refer to id field as the pk. So when you are saying filter(content_type__pk=... it is similar to filter(content_type__id...

The double underscore (__) means a reference to field of that model. You can keep stacking these:

Car.objects.filter(category__supercategory__name = "Nice Cars")

if you had a model Car with a foreign key to Category, which in turn had foreign key to SuperCategory which had a field named name.

Anyone correct me if I am wrong.

drozzy
yes, of course. Somehow because it was content_type I started imagining it was more complicated than usual. Thanks.
interstar
A: 

If you don't understand Django's double-underscore lookup notation, you need to read up on queries generally before delving into the generic relations. This is basic, and fundamental to all Django queries. Don't try to run before you can walk.

Start with the documentation for lookups across relationships.

Daniel Roseman
I agree with this answer ONLY because you should consider generics as the LAST resort. Usually you don't need them, and you will know when you do. Some of the stuff I did with generics could still be implemented using regular models, and in hindsight perhaps would have been a better solution.
drozzy
Actually, I know full well that I need them. I'm a django noob, not a development one ;-)
interstar
Well, ok then. May the force be with you!
drozzy