I have a simple foreign key relationship between two tables. I am able to save the parent, but am unable to save the child which has a foreign key to the parent. This is what my models look like:

class Product(models.Model):
    month_choices   = tuple((m,m) for m in calendar.month_abbr[1:])
    year_choices    = tuple((str(n), str(n)) for n in range(2004, datetime.now().year +2 ))
    id              = models.AutoField(primary_key = True)
    title           = models.CharField(max_length = 1024)
    product_type    = models.ForeignKey(ProductType)
    month           = models.CharField(max_length =3, choices=month_choices)
    year            = models.CharField(choices=year_choices, max_length = 4)
    project         = models.CharField(max_length = 15, null = True, blank = True)
    url             = models.URLField(null = True, blank = True)
    export_to_xsede = models.BooleanField()
    #def __str__(self):
    #    return str(self.id)
    class Meta:
        db_table = "product"

class ProductResource(models.Model):
    CHOICES             = (('A','A'),('B','B'),('C','C'),('D','D'),('E','E'))
    id                  = models.AutoField(primary_key = True)
    product             = models.ForeignKey(Product)
    resource            = models.CharField(choices=CHOICES, max_length = 15)

And my views:

class PublicationForm(forms.ModelForm):
        title = forms.CharField(widget=forms.TextInput(attrs={'size':'70'}),required=False)
        url = forms.CharField(widget=forms.TextInput(attrs={'size':'70'}),required=False)
        class Meta:
            model = Product
class ResourceForm(forms.ModelForm):
        resource = forms.MultipleChoiceField(choices=ProductResource.CHOICES, widget = forms.CheckboxSelectMultiple)
        class Meta:
            model = ProductResource

I save the parent:

saved_publication = publications_form.save()

but am unable to save the resource form:

resource_form = ResourceForm(request.POST, instance = saved_publication)
resource_form.product = saved_publication
resource_form.save()

When I print resource_form.errors, I get:

<ul class="errorlist"><li>product<ul class="errorlist"><li>This field is required.</li></ul></li></ul>

I have no idea why the foreign key is not getting set in this case.

有帮助吗?

解决方案

I'm assuming you do not want to display the product field on the form, so you should exclude it from the form so the validation will pass:

class ResourceForm(forms.ModelForm):
    resource = forms.MultipleChoiceField(choices=ProductResource.CHOICES, widget = forms.CheckboxSelectMultiple)
    class Meta:
        model = ProductResource
        exclude = ['product']

Then in the view, just set the product manually after calling is_valid(). Just be sure to pass commit=False on the form.save() so that it will not actually save to the database until after you set the product. For example

...
saved_publication = publications_form.save()

resource_form = ResourceForm(request.POST)
if resource_form.is_valid():
    resource = resource_form.save(commit=False)
    resource.product = saved_publication
    resource.save()
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top