在中间模型中保存ManyToMany字段数据的问题

时间:2011-04-11 12:47:39

标签: django many-to-many relationship django-orm

首先,对不起我的英语。

我有这个结构,想法是: 产品可以有很多供应商,供应商自己也有产品

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

当我添加产品时,它必须与供应商相关,我使用这种类型的逻辑:

  1. 解析POST数据字段“stock”,其中存储供应商的ID
  2. 然后在for循环中,我按照ID获取供应商实例,该实例以前是从POST获得的,并存储在“供应商”中
  3. 对于每个“供应商”我按ID
  4. 获取实例
  5. 然后使用Supplier.add_product模型函数将其添加到数据库
  6. 问题是,只有列表中的最后一个供应商才会添加到数据库

    希望我解释了这个问题。

2 个答案:

答案 0 :(得分:2)

您想要更改此内容:

data.get('stock','')

到此:

data.getlist('stock')

QueryDict.get('foo')仅返回foo的一个值,即使foo有多个值也是如此。请参阅documentation for QueryDict.getlist()

答案 1 :(得分:2)

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