简体   繁体   English

验证时读取文件后,带有FileField的Django Model Admin无法读取save_model中的文件

[英]Django Model Admin with FileField cannot read file in save_model after reading file when validating

I have a model with a FileField and I want to read the contents of the file before saving it in the Django admin. 我有一个带FileField的模型,我想先读取文件的内容,然后再将其保存在Django管理员中。 I need to verify the file is formatted correctly and also to parse version information out of it and save it into the model. 我需要验证文件的格式是否正确,还要从中解析出版本信息并将其保存到模型中。 I have written code for validation and can successfully validate the file, but it seems I cannot save the version information from the file in the save_object method after i successfully run the validation. 我已经编写了用于验证的代码,并且可以成功验证文件,但是在成功运行验证之后,似乎无法在save_object方法中保存文件的版本信息。 If i skip using the validation, the code in the save_object method works as expected and I can read the file contents and save the version information into the model. 如果我跳过使用验证,则save_object方法中的代码将按预期工作,并且我可以读取文件内容并将版本信息保存到模型中。 I just can't get them to both work at the same time. 我只是不能让他们同时工作。

# models.py:

# the validation works
def validate_file_contents(value):
        contents = value.read()
        first_line, rest_of_file = contents.split('\n', 1)
        if not validate_file_format(rest_of_file):
            raise ValidationError("File is not formatted correctly.")
        if not parse_version(first_line):
            raise ValidationError("The file does not contain correctly formatted version information.")

class MyModel(models.Model):
    file = models.FileField(validators=[validate_file_contents])
    version = models.CharField(max_length=100, null=True, blank=True)

# admin.py:

class MyModelAdmin(admin.ModelAdmin):
    fields = ['file',]
    list_display = ['file', 'version']
    list_filter = ['file', 'version']

    def save_model(self, request, obj, form, change):
        contents = request.FILES['file'].read()
        # contents is empty after successful validation! It is not empty if validation is skipped.

        first_line = contents.split('\n', 1)[0]
        obj.version = parse_version(first_line)
        obj.save()

How can I both validate the file and save the version information? 如何既验证文件又保存版本信息? I am using Django 1.10 and Python 2.7. 我正在使用Django 1.10和Python 2.7。

read() works the way that it uses a pointer of position which you are reading from the file. read()工作方式是使用您正在从文件中读取的位置指针。 So as you read the file, the pointer moves toward its end, until it's on the very end. 因此,当您读取文件时,指针会移到文件的末尾,直到最后。 So calling read() again will return nothing, because you're pointing on the end of the file now. 因此,再次调用read()不会返回任何内容,因为您现在指向的是文件末尾。

To read the file again, use seek(0) first, which will move the pointer to the start of the file again. 要再次读取文件,请首先使用seek(0) ,它将指针再次移至文件的开头。

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

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