2017-01-23 30 views
0

我有一個帶有FileField的模型,我想在將文件保存到Django管理員中之前先讀取該文件的內容。我需要驗證文件格式是否正確,並且解析版本信息並將其保存到模型中。我已經編寫了用於驗證的代碼,並且可以成功驗證該文件,但似乎在成功運行驗證後,我無法從save_object方法中的文件中保存版本信息。如果我跳過驗證,save_object方法中的代碼按預期工作,我可以讀取文件內容並將版本信息保存到模型中。我無法讓他們同時工作。使用FileField的Django模型管理員在驗證後讀取文件後無法讀取save_model中的文件

# 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() 

我該如何驗證文件並保存版本信息?我正在使用Django 1.10和Python 2.7。

回答

1

read()的工作方式,它使用您正在從文件中讀取的位置指針。所以當你閱讀這個文件時,指針就會朝着它的終點移動,直到它結束。所以再次調用read()將不會返回任何內容,因爲您現在指向文件末尾。

要再次讀取文件,請首先使用seek(0),這會再次將指針移動到文件的起始位置。

+0

太棒了,謝謝!現在所有的作品:) – Peconia