Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Override a model field in Django!
from django.db.models.fields.related import ReverseSingleRelatedObjectDescriptor
def override_model_field(model, name, column, field):
"""Force override a field in a Django Model.
Usage: override_model_field(
MyModel, models.ForeignKey(OtherModel), 'other', 'other_id')
:type model: django.db.models.base.ModelBase
:type name: basestring
:type column: basestring
:type field: django.db.models.fields.Field
"""
class FieldOverrideProxy(type(field)):
# noinspection PyMissingConstructor
def __init__(self, original_field):
self.original_field = original_field
self.new_field = field
self.name = self.new_field.name = name
self.attname = self.new_field.attname = column
self.default = original_field.default
self.new_field.verbose_name = (field.verbose_name or
original_field.verbose_name)
def __getattr__(self, item):
try:
return getattr(self.new_field, item)
except AttributeError:
return getattr(self.original_field, item)
for i, f in enumerate(model._meta.fields):
if f.name == name:
field_proxy = FieldOverrideProxy(f)
model._meta.fields[i] = field_proxy
break
else:
raise TypeError('Model {!r} does not have a field {!r}.'
.format(model, name))
model.add_to_class(name, ReverseSingleRelatedObjectDescriptor(field_proxy))
# Example usage:
from django.db import models
class ChildModel(models.Model):
pass
class TheModel(models.Model):
child = models.ForeignKey(ChildModel)
class ChildModelProxy(ChildModel):
class Meta:
proxy = True
class TheModelProxy(TheModel):
class Meta:
proxy = True
override_model_field(TheModelProxy, 'child', 'child_id',
models.ForeignKey(ChildModelProxy))
@shadeofblue

This comment has been minimized.

Copy link

shadeofblue commented May 11, 2016

@carymrobbins hi, what's the license associated with the snippet above? I'd like to use it in a closed-source project if you have nothing against it...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.