In Django i have a model that represents an image with a description that has Foreign Key to another model, this model uses an StdImageField to save the image and auto create a thumbnail. This model also has a choice field with two options representing the type of image.
In my admin i show this model as an inline of the main model, however i'd like to show this model as two separate inlines in the admin as if they were two separate types of objects to the user, for this i'm using 2 proxy models and registering them instead.
The problem is that when i use this proxy models the StdImageField wont resize the uploaded image nor create a thumbnail. I believe this is due to the issue described here
My code is the following (stripped down for the purpose):
models.py
from django.db import models
from stdimage import StdImageField
class MainModel(models.Model):
some_field = models.CharField(max_length = 2)
class SomeModel(models.Model):
SOME_MODEL_TYPE_CHOICES = (
('t1','Type 1'),
('t2','Type 2'),
)
main_model = models.ForeignKey(to='MainModel')
pic = StdImageField(upload_to='img', size =(200,200), thumbnail_size = (100,100))
pic_type = models.CharField(max_length = 2, choices = SOME_MODEL_TYPE_CHOICES)
class SomeModelT1Manager(models.Manager):
def get_query_set(self):
return super(SomeModelT1Manager, self).get_query_set().filter(pic_type='t1')
class SomeModelT1(SomeModel):
objects = SomeModelT1Manager()
class Meta:
proxy = True
def save(self, *args, **kwargs):
if not self.pk:
self.pic_type = 't1'
super(SomeModelT1, self).save(*args,**kwargs)
class SomeModelT2Manager(models.Manager):
def get_query_set(self):
return super(SomeModelT2Manager, self).get_query_set().filter(pic_type = 't2')
class SomeModelT2(SomeModel):
objects = SomeModelT2Manager()
class Meta:
proxy = True
def save(self, *args, **kwargs):
if not self.pk:
self.pic_type = 't2'
super(SomeModelT2, self).save(*args, **kwargs)
admin.py
from django.contrib
import admin
from test_app.models import *
class SomeModelT1Inline(admin.StackedInline):
model = SomeModelT1
exclude = ('pic_type',)
class SomeModelT2Inline(admin.StackedInline):
model = SomeModelT2
exclude = ('pic_type',)
class MainModelAdmin(admin.ModelAdmin):
inlines = [
SomeModelT1Inline,
SomeModelT2Inline
]
admin.site.register(MainModel, MainModelAdmin)
So my question is wheter there is another way of doing this or how do i correct this issue in stdimage. I think the problem could be that contribute_to_class
never gets called in StdImageField when in the Proxy context, mainly because __metaclass__
is not set to models.S开发者_StackOverflow中文版ubfieldBase
as explained in the django documentation for custom model fields
However that's only a wild guess as django's FileField or ImageField don't set that either.
Just a guess without any debugging: The StdImageField
's contribute_to_class
method registers some signal listeners for the orginal SomeModel
for post_init
and post_save
. These handlers don't get called if the sender
is a proxy model.
One a bit hackish way around this could be making your own signal receivers for the proxy models that send out the post_save
and post_init
signals with SomeModel
as sender..
EDIT: You could try putting this at the end of your models.py
; it's quite a hack and probably cause some errors if you would have to register different handlers for the original model and the proxy models...
from django.db.models.signals import post_save, post_init
from django.dispatch import receiver
@receiver(post_save, sender=SomeModelT1)
def post_save_handler(sender, instance, **kwargs):
post_save.send(sender=SomeModel, instance=instance, **kwargs)
@receiver(post_init, sender=SomeModelT1)
def post_init_handler(sender, instance, **kwargs):
post_init.send(sender=SomeModel, instance=instance, **kwargs)
精彩评论