我有2个型号A和B;在django Admin中创建B实例时,我希望自动添加外键。
在下面的示例中,我尝试使用自定义表单,但我还尝试在模型中使用save
,但是没有引发ValidationError
我有以下代码:
在模特中:
class A(models.model):
content = models.TextField()
Class B(models.model):
a = models.ForeignKey(A, related_name='bs', on_delete=models.CASCADE)
content = models.TextField()
形式:
class AdminBModelForm(forms.ModelForm):
class Meta:
model = B
fields = ['content']
def save(self, commit=True):
obj = super().save(commit=False)
obj.a_id = A.objects.first()
if obj.a_id is None:
raise ValidationError('You first need to set A')
obj.save()
return obj
在admin:
class BAdmin(admin.ModelAdmin):
model = B
form = AdminBModelForm
错误:IntegrityError - 列" _id"中的空值违反非空约束
答案 0 :(得分:3)
首先,请注意,您不应将模型对象分配给a_id
字段。你可以这样做:
obj.a = A.objects.first()
或:
a = A.objects.first()
if a is not None:
obj.a_id = a.id
接下来,如果您无法保证A.objects.first()
不是None
,那么您需要在clean
方法中进行检查。在save
或save_model
方法中提出验证错误为时已晚。
class AdminBModelForm(forms.ModelForm):
def clean(self):
cleaned_data = super().clean()
if not A.objects.exists():
raise forms.ValidationError("Cannot save B until an A has been created")
return cleaned_data
最后,在Django管理员中设置值的常用方法是覆盖save_model
方法。
class BAdmin(admin.ModelAdmin):
model = B
fields = ['content']
def save_model(self, request, obj, form, change):
obj.a = A.objects.first()
super().save_model(request, obj, form, change)
答案 1 :(得分:0)
分配A对象时出现轻微错误。试试这个:
class AdminBModelForm(forms.ModelForm):
class Meta:
model = B
fields = ['content']
def save(self, commit=True):
obj = super(AdminBModelForm, self).save(commit=False)
obj.a = A.objects.first() # Assigning the object reference
if not obj.a: # No need to check for None explicitly
raise ValidationError('You first need to set A')
obj.save()
return obj