Python Django:如何防止模型表单字段呈现,但在验证中包含它们?
假设我有以下模型:Python Django:如何防止模型表单字段呈现,但在验证中包含它们?,python,django,validation,django-forms,Python,Django,Validation,Django Forms,假设我有以下模型: class Folder(models.Model): name = models.CharField(default='untitled', max_length=255) parent = models.ForeignKey('self', null=True, blank=True) root = models.ForeignKey('self', null=True, blank=True) user = models.ForeignK
class Folder(models.Model):
name = models.CharField(default='untitled', max_length=255)
parent = models.ForeignKey('self', null=True, blank=True)
root = models.ForeignKey('self', null=True, blank=True)
user = models.ForeignKey(settings.AUTH_USER_MODEL)
在我的应用程序中,此类用于表示两种类型的文件夹:普通文件夹对象和所谓的root_folder-object,它既没有父文件夹,也没有根FK集
我使用custom clean()创建了一个定制的ModelForm,它的工作方式很有魅力(根据unittests和手动测试):
因此,因为我的根文件夹只是一个带有空白FKs的普通文件夹对象,所以我甚至不想在创建时向用户显示这些字段。我为此创建了另一个表单:
class AddRootFolderForm(FolderForm):
class Meta:
model = Folder
exclude = ['parent', 'root', 'user']
如您所见,我也排除了用户,该值将在视图中设置。目前,这是我的视图代码:
@login_required
def create_rootfolder(request):
if request.method == 'POST':
form = FolderForm(data = request.POST,
user = request.user)
else:
form = AddRootFolderForm()
if form.is_valid():
new = form.save()
return redirect('show_rootfolder', root_id = new.id)
return render(request, 'create_rootfolder.html',
{ 'form': form })
整个设置都在运行,但看起来骇人听闻。是否有更好的方法向用户隐藏某些字段(意思是:甚至不将其显示为隐藏字段),而是将其包含在验证中?我的主要问题是,我不能使用相同的表单来显示和验证,因为如果我使用AddRootFolderForm作为单个表单实例,则排除的字段将不会被验证
我知道我可以在构造函数中动态地排除字段,我甚至尝试过这样做,但它使我的构造函数膨胀到50 LOC,这看起来不干净
那么,哪种最好的方法可以验证所有字段的模型,即使这些字段没有包含在向用户显示的表单中?为什么要验证字段,而不是在表单中使用 清理过程是检查用户发布的数据的方法。模型操作所需的其余数据必须在表单验证后添加
if form.is_valid():
new = form.save(commit=False)
new.user = request.user
...
new.save()
接下来(非常好),我将使用表单来包含业务逻辑。即,用户只能将文件夹添加到自己拥有的根文件夹中。因此,考虑一个(要创建的)文件夹有效,文件夹的用户必须与文件夹的根文件夹的用户相同。但不会对表单中排除的字段执行清除过程。因此,您必须从表单clean过程中手动迭代所有排除的clean_字段过程。看起来有点难看,对不起。这正是我的问题!如果排除字段,则它们不在
已清理的\u数据中
,因此,我无法真正验证它们。我试图通过使用不同的表单进行显示和验证来解决这个问题,但它似乎不是pythonic,不是DRY,而是dirty。对不起,我错了。您不需要验证它们!只需使用前面描述的execute方法来添加逻辑
if form.is_valid():
new = form.save(commit=False)
new.user = request.user
...
new.save()