2011-04-11 42 views
1

首先,我的英语很抱歉。在中介模式下保存ManyToMany字段数据时出现问题

我有这样的结构,思路是: 产品可以有很多供应商和供应商自己拥有的产品

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() 

当我添加的产品,它必须与供应商(S),我用这个类型逻辑:

  1. 解析POST数据字段“股票”,其中供应商的ID的存储
  2. 然后,在for循环我得到例如用于由ID,这是以前从POST得到的供应商,并存储在“供应商“
  3. 对于每一个‘供应商’我得到例如,通过ID
  4. 然后将它们与Supplier.add_product模型的功能添加到数据库

的问题是,从下表中只剩下最后的供应商被添加到数据库

希望我解释了这个问题。

回答

2

另一种解决方案是将您的表单字段更改为ModelMultipleChoiceField。然后,您将能够迭代form.cleaned_data ['stock'],它将为您提供所选供应商的实际实例。这样可以避免直接处理POST QueryDict,也不需要手动执行供应商查询。 OMG!

+0

谢谢,它也可以工作,还有更多的“Django-way”。 – Igor 2011-04-11 13:52:58

2

你想改变这一点:

data.get('stock','') 

这样:

data.getlist('stock') 

QueryDict.get('foo')只返回foo一个值,即使有对foo多个值。请参阅documentation for QueryDict.getlist()

+0

OMG!它的工作原理,无法想象它会如此轻松!谢谢:)顺便说一句,我试图使用数据['股票'],但我也没有返回列表。 – Igor 2011-04-11 13:41:48