Проблема с сохранением данных поля ManyToMany в промежуточных моделях - PullRequest
1 голос
/ 11 апреля 2011

Прежде всего, извините за мой английский.

У меня есть такая структура, идея такова: у продукта может быть много поставщиков, а у самого поставщика есть продукты

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 "склад", где хранятся идентификаторы поставщика
  2. Затем вцикл я получаю экземпляр для поставщика по идентификатору, который был ранее получен из POST и хранится в «поставщиках»
  3. Для каждого «поставщика» я получаю экземпляр по идентификатору
  4. Затем добавляем их в базус функцией модели Supplier.add_product

Проблема в том, что в базу данных добавлен только последний поставщик из списка

Надеюсь, я объяснил проблему.

Ответы [ 2 ]

2 голосов
/ 11 апреля 2011

Другое решение - изменить поле формы на ModelMultipleChoiceField. Затем вы сможете выполнить итерацию form.cleaned_data ['stock'], которая даст вам фактические экземпляры поставщика, которые были выбраны. Это позволяет избежать непосредственного обращения с POST QueryDict, а также устраняет необходимость выполнять запросы поставщика «вручную».

2 голосов
/ 11 апреля 2011

Вы хотите изменить это:

data.get('stock','')

к этому:

data.getlist('stock')

QueryDict.get('foo') возвращает только одно значение для foo, даже если для foo есть несколько значений. См. документацию для QueryDict.getlist().

...