在 Django 中,我有一个代表图像的模型,其描述具有另一个模型的外键,该模型使用 StdImageField 来保存图像并自动创建缩略图。该模型还有一个选择字段,其中包含两个表示图像类型的选项。
在我的管理中,我将此模型显示为主模型的内联,但是我想在管理中将此模型显示为两个单独的内联,就好像它们是用户的两种不同类型的对象,为此我我正在使用 2 个代理模型并改为注册它们。
问题是,当我使用此代理模型时,StdImageField 不会调整上传图像的大小,也不会创建缩略图。我相信这是由于描述的问题 here
我的代码如下(为此目的进行了精简):
模型.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)
管理员.py
来自 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)
所以我的问题是是否有另一种方法可以做到这一点,或者我该如何在 stdimage 中纠正这个问题。我认为问题可能是 contribute_to_class
在代理上下文中从未在 StdImageField 中调用,主要是因为 __metaclass__
未设置为 models.SubfieldBase
如 django documentation for custom model fields 中所述
然而,这只是一个大胆的猜测,因为 django 的 FileField 或 ImageField 也没有设置它。
最佳答案
只是猜测,没有任何调试:StdImageField
的 contribute_to_class
方法为 post_init 的原始
和 SomeModel
注册了一些信号监听器post_save
。如果 sender
是代理模型,则不会调用这些处理程序。
解决这个问题的一个有点 hackish 的方法可能是为发送 post_save
和 post_init
信号的代理模型制作你自己的信号接收器 SomeModel
作为发件人..
编辑:您可以尝试将它放在 models.py
的末尾;如果您必须为原始模型和代理模型注册不同的处理程序,这是一个很大的 hack 并且可能会导致一些错误...
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)
关于使用代理模型时 Django StdImage 将不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6688586/