如何为外键django创建表单

时间:2015-01-12 06:12:01

标签: python django django-forms

模型,

class Publication(models.Model):
    name=models.CharField(max_length=128)
    address=models.CharField(max_length=500)
    website=models.URLField()

    def __unicode__(self):
        return self.name

class Book(models.Model):
    name=models.CharField(max_length=128)
    publication=models.ForeignKey(Publication)
    author=models.CharField(max_length=128)
    slug=models.SlugField(unique=True)

    def __unicode__(self):
        return self.name

    def save(self,*args,**kwagrs):
        self.slug=slugify(self.slug)
        super(Book,self).save(*args,**kwagrs)

我尝试为发布对象创建表单。哪个工作正常。但是我可以为Book对象制作表单,因为它有作为外键的发布。

forms.py,

class PublicationForm(forms.ModelForm):
    name = forms.CharField(max_length=128, help_text="Please enter the publication name.")
    address = forms.CharField(max_length=128, help_text="Please enter the address for publication.")
    website=forms.URLField(max_length=200, help_text="Please enter the URL of publication.")
    class Meta:
        model = Publication

如何为具有发布作为外键的书籍对象创建表单。

更新

我已尝试将图书对象的表格作为

class BookForm(forms.ModelForm):
    name = forms.CharField(max_length=128, help_text="Please enter the name.")
    author = forms.CharField(max_length=128, help_text="Please enter the name of the autthor.")
    slug = forms.SlugField(help_text="Please enter the slug")
    publication = forms.ModelMultipleChoiceField(
                                        queryset=Publication.objects.all()
                                        )

    class Meta:
        model = Book
        fields = ('name', 'author','slug','publication')

但是当我提交表单时,它会抛出错误,

Cannot assign "[<Publication: C# in Depth>]": "Book.publication" must be a "Publication" instance.

3 个答案:

答案 0 :(得分:0)

请查看此ModelChoiceField

publication = forms.ModelChoiceField(queryset=Book.objects.all())

答案 1 :(得分:0)

尝试在视图中链接它们。使用save(commit = False),您可以创建一个等待完成其数据的Book对象。完成书籍对象后,可以使用其所有外键保存它

if request.method == 'POST':
    bf = BookForm(request.POST)
    publication_id = request.POST.get('publication_id',0)
    if bf.is_valid():
        if publication_id:
            book = bf.save(commit=False)
            book.publication_id = publication_id
            book.save()
        else:
            # functional error.
    else:
        # functional  error.

答案 2 :(得分:0)

当您使用ModelMultipleChoiceField时,它在表单中提供了Publication的查询集,并且您在BookPublication模型之间使用了外键关系,因此模型形式无法保存publication,因为它没有获得publication个对象。所以你可以这样做来解决这个问题:

class BookForm(forms.ModelForm):
    name = forms.CharField(max_length=128, help_text="Please enter the name.")
    author = forms.CharField(max_length=128, help_text="Please enter the name of the autthor.")
    slug = forms.SlugField(help_text="Please enter the slug")
    publication = forms.ChoiceField(
        choices=[(x.id,x.name) for x in Publication.objects.all()]
         )

    def save(self, commit=True):
      instance = super().save(commit=False)
      pub = self.cleaned_data['publication']
      instance.publication = Publication.objects.get(pk=pub)
      instance.save(commit)
      return instance


    class Meta:
        model = Book
        fields = ('name', 'author','slug')

或者您可以像这样使用ModelMultipleChoiceField:

class BookForm(forms.ModelForm):
    name = forms.CharField(max_length=128, help_text="Please enter the name.")
    author = forms.CharField(max_length=128, help_text="Please enter the name of the autthor.")
    slug = forms.SlugField(help_text="Please enter the slug")
    publication = forms.ModelMultipleChoiceField(
                                        queryset=Publication.objects.all()
                                        )
    def save(self, commit=True):
       instance = super().save(commit=False)
       pub = self.cleaned_data['publication']
       instance.publication = pub[0]
       instance.save(commit)
       return instance

    class Meta:
        model = Book
        fields = ('name', 'author','slug')