简体   繁体   English

在Django管理区域中引发ValidationError后无法更改模型实例

[英]Cannot change model instance after a ValidationError is thrown in django admin area

Imagine a model like this: 想象一个这样的模型:

class CFile(models.Model):
   filepath   = models.FileField(upload_to=...)
   collection = models.ForeignKey("FileCollection",null=True)
   ... # other attributes that are not relevant

   def clean(self):
     bname = os.path.basename
     if self.collection:
       cfiles = self.baseline.attachment_set.all()
       with_same_basename = filter(lambda e: bname(e.filepath.path) == bname(self.filepath.path),cfiles)
       if len(with_same_basename) > 0:
         raise ValidationError("There already exists a file with the same name in this collection")   

class FileCollection(models.Model):
  name = models.CharField(max_length=255)
  files= models.ManyToManyField("CFile")

I want to disallow the upload of a CFile if there already exists a CFile with the same basename, that's why I added the clean . 如果已经存在具有相同基本名称的CFile,我想禁止CFile的上传,这就是为什么我添加clean的原因。 The problem is: 问题是:

  • I upload a CFile, with the name file1.png -> gets uploaded because no other files with this name exist 我上传了一个名为file1.png >的CFile,因为没有其他使用此名称的文件而被上传
  • I upload another CFile, with the name file1.png -> I get the expected error that I already have a file with this name. 我上传了另一个CFile,名称为file1.png >我得到了我已经有一个具有此名称的文件的预期错误。 So, I try to change the file, and upload a file with a different name ( file2.png ). 因此,我尝试更改文件,并上传一个具有不同名称的文件( file2.png )。 The problem is, I stopped via pdb in the clean, and the model instance is still file1.png . 问题是,我通过pdb干净地停止了运行,并且模型实例仍然是file1.png I imagine this happens because of my ValidationError and django allows me to "correct my mistake". 我想象发生这种情况是因为我的ValidationError,而django允许我“更正我的错误”。 The problem is I cannot correct it if I cannot upload another file. 问题是如果我不能上传另一个文件,我将无法纠正它。 How can I handle this? 我该如何处理?

EDIT: This happens in the admin area, sorry for forgetting to mention this before. 编辑:这发生在管理区域,对不起忘记提及此。 I don't have anything custom ( besides inlines = [ FileInline ] ). 我没有任何自定义(除了inlines = [ FileInline ] )。

I think the clearest way is to declare another field in your model for filename and make it unique for every collection. 我认为最清晰的方法是在模型中为文件名声明另一个字段,并使其对于每个集合都是唯一的。 Like this: 像这样:

class CFile(models.Model):
   filepath   = models.FileField(upload_to=...)
   collection = models.ForeignKey("FileCollection",null=True, related_name='files')
   filename = models.CharField(max_length=255)
   ... # other attributes that are not relevant

    class Meta:
        unique_together = (('filename', 'collection'),)

    def save(self, *args, **kwargs):
        self.filename = bname(self.filepath.path)
        super(CFile, self).save(args, kwargs)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM