Skip to content

Instantly share code, notes, and snippets.

@ashchristopher
Created January 14, 2011 21:15
Show Gist options
  • Save ashchristopher/780253 to your computer and use it in GitHub Desktop.
Save ashchristopher/780253 to your computer and use it in GitHub Desktop.
Generic Foreign Keys WTF?!
In models.py
--------------------
from datetime import datetime
from django.db import models
from django.contrib.sites.models import Site
from django.contrib.contenttypes.models import ContentType
from django.contrib.contenttypes import generic
class Cart(models.Model):
"""
Container to hold all the orders that a user of the website makes including
trips, addons, extras, etc.
"""
date_added = models.DateTimeField(auto_now_add=True)
date_updated = models.DateTimeField(auto_now=True)
site = models.ForeignKey(Site, default=Site.objects.get_current)
order_items = generic.GenericRelation('GenericItem')
class Meta:
abstract = True
class ShoppingCart(Cart):
name = models.CharField(max_length=50)
class Item(models.Model):
date_added = models.DateTimeField(auto_now_add=True, default=datetime.now())
date_updated = models.DateTimeField(auto_now=True, default=datetime.now())
class Meta:
abstract = True
class GenericItem(Item):
content_type = models.ForeignKey(ContentType)
object_id = models.IntegerField()
content_object = generic.GenericForeignKey('content_type', 'object_id')
class BookItem(GenericItem):
title = models.CharField(max_length=50)
num_pages = models.IntegerField()
def __unicode__(self):
return "Book: %s" % self.title
class MovieItem(GenericItem):
title = models.CharField(max_length=50)
running_time = models.IntegerField()
rating = models.IntegerField()
def __unicode__(self):
return "Movie: %s" % self.title
In admin.py:
---------------
from django.contrib import admin
from django.contrib.contenttypes.generic import GenericTabularInline
from foo.models import *
class BookItemAdmin(GenericTabularInline):
model = BookItem
class MovieItemAdmin(GenericTabularInline):
model = MovieItem
class MyCartAdmin(admin.ModelAdmin):
inlines = (
MovieItemAdmin,
BookItemAdmin,
)
admin.site.register(ShoppingCart, MyCartAdmin)
I created a Shopping Cart object, and populated the items. Then I went to the shell:
>>> from foo.models import *
>>> s = ShoppingCart.objects.all()[0]
>>> s.order_items.all()
[<GenericItem: GenericItem object>, <GenericItem: GenericItem object>]
>>> o = s.order_items.all()[0]
>>> o.content_object
<ShoppingCart: ShoppingCart object>
WTF? This *should* be returning one of either MovieItem or BookItem should it not?
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment