开发者

Django StdImage won't work when using a proxy model

开发者 https://www.devze.com 2023-03-20 08:47 出处:网络
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 a

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)
0

精彩评论

暂无评论...
验证码 换一张
取 消