我有一个包含两个实体Person
和Code
的模型。 Person
引用了Code
两次,Person
可以是代码的user
或approver
。
我想要实现的目标如下:
Person.cusman
,则无需采取进一步措施。Person.cusman
,则帮助程序代码会查找Person
的其他属性(来自外部数据库),并创建新的Person
实体。我已经实现了由pre_save
信号触发的功能,该功能可以动态创建缺失的Person
。只要我使用python manage.py shell
创建Code
且不存在Person
,它就可以正常工作。
但是,当我尝试使用管理表单或Code
后代添加新的CreateView
时,我总是在HTML表单上收到以下验证错误:
Select a valid choice. That choice is not one of the available choices.
显然在单击“保存”按钮和Code.save()
方法之间会发生验证,但我无法弄清楚它是哪一个。在pre_save
创建引用的实体之前,你能帮助我覆盖哪种方法来接受无效的外键吗?
class Person(models.Model):
cusman = models.CharField(
max_length=10,
primary_key=True)
name = models.CharField(max_length=30)
email = models.EmailField()
def __unicode__(self):
return u'{0} ({1})'.format(self.name, self.cusman)
class Code(models.Model):
user = models.ForeignKey(
Person,
on_delete=models.PROTECT,
db_constraint=False)
approver = models.ForeignKey(
Person,
on_delete=models.PROTECT,
related_name='approves',
db_constraint=False)
@receiver(pre_save, sender=Code)
def create_referenced_person(sender, instance, **kwargs):
def create_person_if_doesnt_exist(cusman):
try:
Person = Person.objects.get(pk=cusman)
except Person.DoesNotExist:
Person = Person()
cr = CusmanResolver()
Person_details = cr.get_person_details(cusman)
Person.cusman = Person_details['cusman']
Person.name = Person_details['name']
Person.email = Person_details['email']
Person.save()
create_Person_if_doesnt_exist(instance.user_id)
create_Person_if_doesnt_exist(instance.approver_id)
class CodeAddForm(ModelForm):
class Meta:
model = Code
fields = [
'user',
'approver',
]
widgets = {
'user': TextInput,
'approver': TextInput
}
class CodeAddView(generic.CreateView):
template_name = 'teladm/code_add.html'
form_class = CodeAddForm
答案 0 :(得分:3)
您误解了一件事:您不应该使用TextField
来填充ForeignKey,因为使用下拉/单选按钮填充django外键以引用另一个模型中对象的id
。您收到的错误表示您提供的错误信息与另一个模型中的任何id
都不匹配(在您的情况下为Person
)。
您可以做的是:不使用ModelForm
,而是使用Form
。致电form.is_valid()
后,您可能还需要做一些额外的工作,但至少可以根据需要编写逻辑代码。