How can make the admin for a ForeignKey('self') ban referring to itself?
我有一个带有forgein键的模型。 例如:
1 2 3 | class Folder(models.Model): name = models.CharField() parent_folder = models.ForeignKey('self', null=True, blank=True, default=None, on_delete=models.CASCADE) |
出于我的目的,我从不希望
编辑:如果您尝试进行分层树布局,就像我一样,您需要注意的另一件事是圆形父关系。 (例如,A的父母是B,B的父母是C,而C的父母是A.)避免这不是这个问题的一部分,但我想我会提到它作为提示。
我个人会在模型级别执行此操作,因此如果您以其他形式重用该模型,您也会收到错误:
1 2 3 4 5 6 7 | class Folder(models.Model): name = models.CharField() parent_folder = models.ForeignKey('self', null=True, blank=True, default=None, on_delete=models.CASCADE) def clean(self): if self.parent_folder == self: raise ValidationError("A folder can't be its own parent") |
如果在表单中使用此模型,请使用查询集,以便不显示模型本身:
1 2 3 4 5 6 7 8 9 10 | class FolderForm(forms.ModelForm): class Meta: model = Folder fields = ('name','parent_folder') def __init__(self, *args, **kwargs): super(FolderForm, self).__init__(*args, **kwargs) if hasattr(self, 'instance') and hasattr(self.instance, 'id'): self.fields['parent_folder'].queryset = Folder.objects.exclude(id=self.instance.id) |
要确保用户在填写外键字段时不选择相同的实例,请在管理表单中实施拒绝该错误值的
在此示例中,模型为
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | from django import forms from django.contrib import admin from .models import Folder class FolderAdminForm(forms.ModelForm): def clean_parent_folder(self): if self.cleaned_data["parent_folder"] is None: return None if self.cleaned_data["parent_folder"].id == self.instance.id: raise forms.ValidationError("Invalid parent folder, cannot be itself", code="invalid_parent_folder") return self.cleaned_data["parent_folder"] class FolderAdmin(admin.ModelAdmin): form = FolderAdminForm admin.site.register(Folder, FolderAdmin) |
编辑:将我的答案与raphv的答案结合起来以获得最大效果。