Search code examples
django-viewsforeign-key-relationshipdjango-class-based-viewsmanytomanyfield

Inside Django class-base CreateView, how to init intermediate model


I have three models, PiItem is the interface of Pi and Items models by "through".

Right now I want to create a new Items instance with new Pi instance and new PiItem instance inside Django CreatedView class.

Somehow I keep getting error message

*

*****MultipleObjectsReturned at /product/ get() returned more than one PiItem*****

*

Any help will be highly appreciated THANKS

here are the models

class Pi(models.Model):
    company = models.ForeignKey(CompanyProfile, related_name='pi', null=True)
    contact = models.ForeignKey(Contact, null=True)

    def __unicode__(self):
        #return u'%s, %s' %(self.company.companyprofile_name, self.reference_id)
        return u'%s' %(self.company.companyprofile_name)



class Items(models.Model):
    product_id = models.CharField("Product ID",max_length=50, blank=False, null=True, unique=True)
    in_pi = models.ManyToManyField(Pi, through='PiItem', blank=True)

    def __unicode__(self):
        return self.product_id


class PiItem(models.Model):
    item_name= models.ForeignKey(Items)
    pi = models.ForeignKey(Pi)

    def __unicode__(self):
        return self.pi.reference_id

and here is my view.py

from django.views.generic.edit import CreateView
from pi.models import Items, PiItem, Pi
from django.shortcuts import get_object_or_404

class AddItemView(CreateView):

    context_object_name = 'Product_list'
    model = Items
    template_name = "product.html"
    fields = "__all__"

    def get_initial(self):
        in_pi = get_object_or_404(PiItem)
        return {
            'in_pi':in_pi
        }

and here is the template

{% extends 'base.html' %}


{% load crispy_forms_tags %}

{% block pi %}

<form action="" method="post">{% csrf_token %}
    {{ form|crispy }}
    {{ form.get_form_class() }}
    <input type="submit" value="Create" />
</form>

Solution

  • Problem most likely is here:

    in_pi = get_object_or_404(PiItem)
    

    You need to filter the PiItem object by passing additional arguments, such as foreigk key to each related model, like:

    in_pi = get_object_or_404(PiItem, item_name=something1, pi=something2)