【发布时间】:2016-04-18 15:01:53
【问题描述】:
我有一个包含两个实体的模型,Person 和 Code。 Person 被Code 引用两次,Person 可以是代码的user,也可以是approver。
我想要达到的目标如下:
- 如果用户提供了现有的
Person.cusman,则无需进一步操作。 - 如果用户提供未知的
Person.cusman,帮助代码会查找Person的其他属性(来自外部数据库),并创建一个新的Person实体。
我已经实现了一个由pre_save 信号触发的函数,它会即时创建缺失的Person。只要我使用python manage.py shell 创建一个不存在Person 的Code,它就可以正常工作。
但是,当我尝试使用管理表单或 CreateView 后代添加新的 Code 时,我总是在 HTML 表单上收到以下验证错误:
Select a valid choice. That choice is not one of the available choices.
显然在单击“保存”按钮和Code.save() 方法之间会发生验证,但我不知道是哪个。你能帮我在pre_save创建引用实体之前,我应该重写哪个方法来接受无效的外键?
models.py
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)
signals.py
@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)
views.py
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
【问题讨论】:
标签: python django django-models django-forms