Skip to content

Instantly share code, notes, and snippets.

@ctbarna
Created August 18, 2014 21:31
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ctbarna/d9ec9e6d16821ec08a7c to your computer and use it in GitHub Desktop.
Save ctbarna/d9ec9e6d16821ec08a7c to your computer and use it in GitHub Desktop.
class ContentTypeForeignKey(models.ForeignKey):
def __init__(self, **kwargs):
if "choices" in kwargs:
kwargs["choices"] = self._process_choices(kwargs["choices"])
# It is possible for `to` to be passed in with **kwargs. Since
# ContentType is hardcoded in for the `to` arg when calling super(),
# this can lead to problems.
if "to" in kwargs:
del kwargs["to"]
super(ContentTypeForeignKey, self).__init__(ContentType, **kwargs)
def _process_choices(self, choices):
"""
Pass in choices as a tuple of two-tuples as you would for a normal
choices kwarg. Unlike a normal choices kwarg, the first item is a
string of the format app_label.model_name.
For example: `("blog.BlogArticle", "Blog Article")` resolves to the
BlogArticle model of the blog app.
"""
processed_choices = ()
for choice in choices:
model_str, form_label = choice
app_label, model = model_str.split(".")
content_type = ContentType.objects.get(app_label=app_label, model=model.lower())
processed_choices += ((content_type.pk, form_label),)
return processed_choices
from south.modelsinspector import add_introspection_rules
add_introspection_rules([], ["^ContentTypeForeignKey"])
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment