无法在Django 1.9

时间:2016-04-18 15:01:54

标签: python django django-models django-forms

我有一个包含两个实体PersonCode的模型。 Person引用了Code两次,Person可以是代码的userapprover

我想要实现的目标如下:

  • 如果用户提供现有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创建引用的实体之前,你能帮助我覆盖哪种方法来接受无效的外键吗?

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

1 个答案:

答案 0 :(得分:3)

您误解了一件事:您不应该使用TextField来填充ForeignKey,因为使用下拉/单选按钮填充django外键以引用另一个模型中对象的id。您收到的错误表示您提供的错误信息与另一个模型中的任何id都不匹配(在您的情况下为Person)。

您可以做的是:不使用ModelForm,而是使用Form。致电form.is_valid()后,您可能还需要做一些额外的工作,但至少可以根据需要编写逻辑代码。