【问题标题】:Django admin: Add a "remove file" field for Image- or FileFieldsDjango 管理员:为 Image- 或 FileFields 添加“删除文件”字段
【发布时间】:2010-04-17 03:49:25
【问题描述】:

我在互联网上寻找一种方法,让用户可以轻松地清空他们在管理员中设置的图像字段/文件字段。

我发现了这个:http://www.djangosnippets.org/snippets/894/。

我真正感兴趣的是 rfugger 在评论中发布的代码:

remove_the_file = forms.BooleanField(required=False)

def save(self, *args, **kwargs):
    object = super(self.__class__, self).save(*args, **kwargs)
    if self.cleaned_data.get('remove_the_file'):
        object.the_file = ''
    return object

当我尝试在我自己的表单中使用它时,我基本上将它添加到我的 admin.py 中,它已经有一个 BlahAdmin。

class BlahModelForm(forms.ModelForm):
    class Meta:
        model = Blah

    remove_img01 = forms.BooleanField(required=False)

    def save(self, *args, **kwargs):
        object = super(self.__class__, self).save(*args, **kwargs)
        if self.cleaned_data.get('remove_img01'):
            object.img01 = ''
        return object

当我运行它时,我得到了错误

调用 Python 对象时超出最大递归深度

在这一行:

object = super(self.__class__, self).save(*args, **kwargs)

当我考虑一下时,很明显它只是无限地调用自己导致错误。我的问题是我无法弄清楚我应该这样做的正确方法是什么。 有什么建议吗?

根据要求提供其他信息:

blah的型号:

class Blah(models.Model):
    blah_name = models.CharField(max_length=25, unique=True)
    slug = models.SlugField()
    img01 = models.ImageField(upload_to='scenes/%Y/%m', blank=True)

    def __unicode__(self):
        return self.blah_name

【问题讨论】:

  • 调用超级方法看起来不错,你确定没有更多或不同的代码吗?也代替object 使用'obj'
  • 感谢提示使用 obj。我不知道是否应该有更多代码,这就是链接中的全部内容。链接上的评论者可能会假设阅读它的人比我更精通 django/python 并且缺少的部分很明显?

标签: python django django-admin django-forms django-models


【解决方案1】:

永远不要使用super(self.__class__, self)!试试下面的例子:

class A(object):
    def m(self):
        super(self.__class__, self).m()

class B(A): pass

B().m()

它会失败并出现同样的错误:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 4, in m
  ... repeated a lot of times ...
RuntimeError: maximum recursion depth exceeded while calling a Python object

让我们看看发生了什么。你为B实例调用A.m方法,所以self.__class__是B和super(self.__class__, self).m指的是同一个方法A.m,所以A.m调用自己而不是调用基类的方法。这会导致无限递归。

【讨论】:

  • 嗨丹尼斯,感谢您的回答。昨天我尝试了: obj = super(BlahModelForm, self).save(*args, **kwargs) 并且按预期工作。想一想,不应该和使用super(self._class_, self).save(*args, **kwargs)的结果一样吗?在第一种情况下,似乎我明确地调用了我所在的类的名称,而不是通过 self._class_。我在这里有什么明显的遗漏吗?
  • 当你在 BlahModelForm 的方法中使用 self.__class__ 时,不保证给你 BlahModelForm。 self 可以是不同类的实例(特别是 BlahModelForm 的子/派生类)。这就是丹尼斯的例子所说明的情况。
【解决方案2】:

我已经在我的机器上对其进行了测试,它可以工作:-)。我完全使用了您的代码。 问题必须在这段代码之外。

请发布一个 sn-p 你如何调用/保存表单和模型的声明Blah。

你是否覆盖了Model的保存方法Blah?

【讨论】:

  • 嗨,maersu,感谢您的关注。我同意这听起来确实像是代码之外的东西。我没有做任何特别的事情来调用表单,我只是在 django admin 中使用它。我没有覆盖模型 Blah 的保存方法。我已经把模型放在上面。
猜你喜欢
  • 1970-01-01
  • 2013-04-15
  • 1970-01-01
  • 2016-08-26
  • 2011-08-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多