15๐
To switch from a model class to a proxy class without hitting the database:
class EntryProxy(Entry):
@property
def category(self):
new_inst = EntryProxy()
new_inst.__dict__ = super(EntryProxy, self).category.__dict__
return new_inst
edit: the snippet above seems not working on django 1.4.
Since django 1.4, I take all value fields manually like this:
class EntryProxy(Entry):
@property
def category(self):
category = super(EntryProxy, self).category
new_inst = EntryProxy()
for attr in [f.attname for f in category.__class__._meta.fields] + ['_state']:
setattr(new_inst, attr, getattr(category, attr))
return new_inst
To switch from a queryset to a child proxy class without hitting database:
class CategoryProxy(Category):
@property
def entry_set(self):
qs = super(CategoryProxy, self).entry_set
qs.model = EntryProxy
return qs
9๐
This is an open Django issue: #10961 (Allow users to override forward and reverse relationships on proxy models with ForeignKey fields)
You can work around it by resetting the fields in question after you define the proxy models:
EntryProxy.add_to_class('category', CategoryProxy)
- [Django]-Celery discover tasks in files with other filenames
- [Django]-How to run a celery worker with Django app scalable by AWS Elastic Beanstalk?
- [Django]-Why is factory_boy superior to using the ORM directly in tests?
2๐
None of the current solutions (including the accepted one) work with Django 2.0.
Building on Matt Schinckelโs work on overriding proxy model relations, hereโs a solution that will work with Django 2.0 and 2.1.
- [Django]-Django REST Framework (DRF): Set current user id as field value
- [Django]-How do I match the question mark character in a Django URL?
- [Django]-How to implement FirebaseDB with a Django Web Application
1๐
This question already has an accepted answer, but wanted to post this for anyone who may come searching.
You can patch the model at runtime with the new field so that relations work as expected. A full example can be seen here โ https://gist.github.com/carymrobbins/8721082
from django.db.models.fields.related import ReverseSingleRelatedObjectDescriptor
def override_model_field(model, field, field_name, column_name):
"""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 field: django.db.models.fields.Field
:type field_name: basestring
:type column_name: basestring
"""
field.name = field_name
field.attname = column_name
for i, f in enumerate(model._meta.fields):
if f.name == field_name:
model._meta.fields[i] = field
break
else:
raise TypeError('Model {!r} does not have a field {!r}.'
.format(model, field_name))
model.add_to_class(field_name,
ReverseSingleRelatedObjectDescriptor(field))
- [Django]-Django Admin app or roll my own?
- [Django]-Filtering dropdown values in django admin
- [Django]-How do I run tests against a Django data migration?
0๐
You can add proxy model to ForeignKey:
class Entry(models.Model):
category = models.ForeignKey(CategoryProxy, on_delete=models.CASCADE)
and now:
entry = EntryProxy.objects.get(pk=1)
entry.category # CategoryProxy instance
- [Django]-VueJS + Django Channels
- [Django]-How to add new languages into Django? My language "Uyghur" or "Uighur" is not supported in Django
- [Django]-Heroku, postgreSQL, django, comments, tastypie: No operator matches the given name and argument type(s). You might need to add explicit type casts
-2๐
Define a property category
on EntryProxy that looks up the CategoryProxy by its id:
class EntryProxy(Entry):
@property
def category(self):
cid = super(EntryProxy, self).category.id
return CategoryProxy.objects.get(id=cid)
class Meta:
proxy = True
- [Django]-Handle `post_save` signal in celery
- [Django]-Django staticfiles not found on Heroku (with whitenoise)
- [Django]-Do we need to upload virtual env on github too?
-2๐
Adapting Bernd Petersohnโs answer slightly, we then have:
class EntryProxy(Entry):
@property
def category(self):
return CategoryProxy.objects.get(id=self.category_id)
This ought to be more economical with the database. For added improvements you could set a private attribute (self._category
) the first time the method is called, then return that all subsequent times.
- [Django]-Ignoring Django Migrations in pyproject.toml file for Black formatter
- [Django]-Django composite unique on multiple model fields
- [Django]-VueJS + Django Channels