Django自动在表单中设置外键(使用基于类的视图)

Pte*_*aur 4 django django-forms

我想使用一个表单从Person页面生成一个新对象(比如一本书),这样新书就会通过外键自动与该Person关联,但是我遇到了使Person正确关联并保存的问题.表格.对于我的模特,我有:

class Person(models.Model):
    p_id = models.PositiveIntegerField(primary_key=True, unique=True)

class Book(models.Model):
    person = models.ForeignKey(Person)
    title = models.CharField(max_length=100)
Run Code Online (Sandbox Code Playgroud)

然后我有一个自定义表单来创建一本书:

class AddBookForm(forms.ModelForm):
    class Meta:
        model = Book
        fields = ('title', 'person',)
        widgets = {
            'person': forms.HiddenInput,
        }
Run Code Online (Sandbox Code Playgroud)

以及创建Book的视图(也给出了Person 的pk(p_id)):

class AddBook(CreateView):
    model = Book
Run Code Online (Sandbox Code Playgroud)

我尝试了各种方法来实现这个目的:

  • 预先填充Person字段get_initial,但由于某些原因,输入设置为隐藏(令人沮丧),这会消失.
  • 修改form_valid视图中的方法,但这仅在表单已经过验证后才会发生,因此我需要在此之前添加Person.
  • 修改clean_person表单类中的方法,但只有在clean方法验证表单后才会发生.

目前,我试图覆盖该clean方法.但是,在表格已经发送清理之后,我不知道如何获得此人.在视图中,我可以访问它Patient.objects.get(p_id=self.kwargs.get('pk')).

有没有什么方法可以在我的视图中将数据添加到表单(作为基于类的视图),它不会被剥离或者是否有某种方式我可以访问Person或p_id外键此时添加clean方法中的数据?

knb*_*nbk 8

你的做法是错误的:这个人不是用户输入,所以这些信息不应该存在于表格中.您可以form_valid按如下方式覆盖该方法:

class AddBook(CreateView):
    model = Book

    def form_valid(self, form):
        form.instance.person_id = self.kwargs.get('pk')
        return super(AddBook, self).form_valid(form)
Run Code Online (Sandbox Code Playgroud)

这将person_id在表单用于保存数据的实例上设置属性,然后调用该super方法以保存该实例并返回重定向.