【问题标题】:'FieldFile' object has no attribute 'full_clean''FieldFile' 对象没有属性 'full_clean'
【发布时间】:2019-09-05 13:37:51
【问题描述】:

我一直在尝试在 django 中的文件字段上实现文件大小验证器,但我无法真正让它工作。

在我添加此验证器之前,一切正常。添加后,我根本无法上传文件。错误提示“文件字段没有 full_clean 属性”。

views.py

from django.shortcuts import render, get_object_or_404
from .models import Oferta, CV
from django.contrib import messages
from django.core.paginator import Paginator

def incarcarecv(req):
    context = {
        'title': "Incarcare CV | Best DAVNIC73"
    }
    if req.method == 'POST':
        nume = req.POST['nume']
        prenume = req.POST['prenume']
        telefon = req.POST['telefon']
        email = req.POST['email']
        cv = req.FILES['CV']
        if(req.user.is_authenticated):
            cv_upload = CV(
            solicitant=req.user,
            nume=nume,
            prenume=prenume,
            telefon=telefon,
            emailContact=email
            )
            cv_upload.CVFile.full_clean()
            cv_upload.CVFile.save(cv.name, cv)  
            cv_upload.save()
            req.user.profile.cvuri.append(cv_upload.id)
            req.user.profile.save()
            messages.success(req, 'CV depus cu succes!')
        else:
            messages.error(req, 'Trebuie sa fii logat pentru a depune CV-ul!')
    return render(req, "../templates/pagini/incarcare-cv.html", context)

models.py

from django.db import models
from django.contrib.auth.models import User
from .validators import validate_file_size

# Create your models here.
class Oferta(models.Model):
    solicitant = models.ForeignKey(User, on_delete=models.CASCADE)
    dataSolicitare = models.DateField(auto_now_add=True)
    cor = models.CharField(max_length=25)
    denumireMeserie = models.CharField(max_length=12)
    locuri = models.IntegerField()
    agentEconomic = models.CharField(max_length=50)
    adresa = models.CharField(max_length=150)
    dataExpirare = models.DateField()
    experientaSolicitata = models.CharField(max_length=200)
    studiiSolicitate = models.CharField(max_length=200)
    judet = models.CharField(max_length=20)
    localitate = models.CharField(max_length=25)
    telefon = models.CharField(max_length=12)
    emailContact = models.EmailField(max_length=40)
    rezolvata = models.BooleanField(default=False)
    def __str__(self):
        return self.cor

class CV(models.Model):
    solicitant = models.ForeignKey(User, on_delete=models.CASCADE)
    dataUploadCV = models.DateField(auto_now_add=True)
    nume = models.CharField(max_length=12)
    prenume = models.CharField(max_length=12)
    telefon = models.CharField(max_length=12)
    emailContact = models.EmailField(max_length=40)
    CVFile = models.FileField(upload_to='documents/%d/%m/%Y', validators=[validate_file_size])
    rezolvata = models.BooleanField(default=False)
    def __str__(self):
        return self.nume + " " + self.prenume + ": " + str(self.CVFile)

验证器.py

from django.core.exceptions import ValidationError


def validate_file_size(value):
    filesize=value.size

    if filesize > 5000000:
        raise ValidationError("Maximum 5MB!")    

我似乎不明白为什么。你能帮我修复我的代码吗? 据我所知, .full_clean() 运行一些默认的 django 验证器 + 模型中设置的验证器。

但实际上它不起作用。

Exception Value:    
'FieldFile' object has no attribute 'full_clean'

您能否向我解释为什么会发生这种情况以及如何让我的验证器运行?

谢谢。

//顺便说一句,有人建议像这样改变行的顺序-

cv_upload.CVFile.save(cv.name, cv) 
cv_upload.CVFile.full_clean()    

但它无论如何都不起作用。

【问题讨论】:

    标签: django


    【解决方案1】:

    正如错误所说,full_clean() 不是模型字段的方法。这是模型本身的一种方法。

    cv_upload.full_clean() 有效。

    但是你应该直接用文件初始化你的cv_upload

    cv_upload = CV(
         solicitant=...,
         ..., 
         CVFile=cv) 
    

    那么您不必单独保存文件,请参阅docs

    另外,您正在运行full_clean(),但没有捕获任何异常。如果验证失败会怎样? ValidationError 将被抛出。如果您没有捕捉到它,您的视图将返回 HTTP 500 错误(它只会崩溃)。

    因此将其包装在 try ... except 子句中:

    try:
        cv_upload.full_clean()
    except ValidationError as e:
        messages.error(request, e)
    else:
        cv_upload.save()
        messages.success(request, "yeah!")
    

    【讨论】:

    • 它有效。介意解释运行 .full_clean 后保存它和你怎么说的区别吗?我认为如果我按照自己的方式做,验证器根本不会运行,因为 .save 是在验证之后。
    • 验证允许您检查所提供的数据是否有效之前将其保存到数据库中(因此您在保存时不会出现异常,或者更糟糕的是,您的数据库)。所以先保存没有意义。
    猜你喜欢
    • 2016-07-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-01
    • 2021-08-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多