1

First of all, sorry for my English.

I have this structure, idea is: Product can have many suppliers, and supplier himself have products

class Supplier(Model):
     title = CharField()

     def add_product(self, **kwargs):
            s2p = Stock(supplier=self, **kwargs)
            s2p.save()

class Product(Model):
    title = CharField()
    stock = ManyToManyField(Supplier, through="Stock")

class Stock(Model):
    in_stock = BooleanField()
    product = ForeignKey(Product, related_name="product_stock")
    supplier = ForeignKey(Supplier, related_name="supplier_stock")



# forms.py
class ProductForm(ModelForm):
    class Meta:
        model = Product

    stock = ModelChoiceField(queryset=Supplier.objects.all(), widget=CheckboxSelectMultiple)        


    # views.py
    def product_edit(request, product_id, template):
        if product_id:
            product = get_object_or_404(Product, pk=product_id)
            else:
            product = Product()

        if request.method == "POST":
            data = request.POST.copy()
            form = ProductForm(data, request.FILES, instance=product)
            if form.is_valid():
                prod = form.save(commit=False)
                if product.id:
                    prod.editedby = product.editedby
                else:
                    prod.createdby = request.user
                    prod.editedby = request.user
                prod.save()
                if "stock" in request.POST:
                    actions.clear_stock() 
                    suppliers = data.get('stock','')
                    for supplier in suppliers: 
                        supp = Supplier.objects.get(pk=supplier)
                        supp.add_product(product=prod)
        else:
            form = ProductForm(instance=product)

        dict = {
            'form': form,
        }

        return render_to_response(template, dict, context_instance=RequestContext(request))

    # actions.py
    def clear_stock():
        s2ps = Stock.objects.all()
        for s2p in s2ps:
            s2p.delete()

When i add product, it must be related to supplier(s), i use this type of logic:

  1. Parsing POST data field "stock", where IDs of supplier is stored
  2. Then in for loop i get instance for supplier by ID, which was previously get from POST, and stored in "suppliers"
  3. For each of "Supplier" i get instance by ID
  4. Then add them to database with Supplier.add_product model function

The problem is, that only last supplier from the list is added to database

Hope I explained the problem.

Igor
  • 479
  • 5
  • 13

2 Answers2

2

You want to change this:

data.get('stock','')

to this:

data.getlist('stock')

QueryDict.get('foo') only returns one value for foo, even if there are multiple values for foo. See the documentation for QueryDict.getlist().

Jordan Reiter
  • 20,467
  • 11
  • 95
  • 161
  • OMG! It works, couldn't imagine it would be so easy! Thanks:) BTW, i tried to use data['stock'], but i also didn't return list. – Igor Apr 11 '11 at 13:41
2

Another solution is to change your form field to a ModelMultipleChoiceField. Then you would be able to iterate form.cleaned_data['stock'] which would give you the actual instances of Supplier which were selected. This avoids dealing with the POST QueryDict directly and also removes the need to do the Supplier queries "manually".

shadfc
  • 6,104
  • 3
  • 25
  • 19