Python 在没有django预构建表单的情况下,如何使用view填充manytomanyfield?

Python 在没有django预构建表单的情况下,如何使用view填充manytomanyfield?,python,django,manytomanyfield,Python,Django,Manytomanyfield,我正在使用django构建一个存储web系统,我对该框架非常熟悉,所以问题是,有一个业务规则,需要两种产品,内部产品和成品。而成品,总是由一个或多个内部产品组成,我有使用多个字段的想法,但现在,我真的不知道如何提取这些数据,这应该是一个多选,从表单中保存在数据库中,有人有任何提示或更好的想法吗 Models.py class Produto(models.Model): codigo = models.CharField(max_length=254, null=True) pr

我正在使用django构建一个存储web系统,我对该框架非常熟悉,所以问题是,有一个业务规则,需要两种产品,内部产品和成品。而成品,总是由一个或多个内部产品组成,我有使用多个字段的想法,但现在,我真的不知道如何提取这些数据,这应该是一个多选,从表单中保存在数据库中,有人有任何提示或更好的想法吗

Models.py

class Produto(models.Model):
    codigo = models.CharField(max_length=254, null=True)
    produto_desc = models.CharField(max_length=200, null=False)
    tipo = models.CharField(max_length=2)
    qtd = models.IntegerField(null=True, default=0)
    created = models.DateTimeField(default=timezone.now, editable=False)
    last_updated = models.DateTimeField(default=timezone.now, editable=False)


    #Relationship Fields
    estrutura = models.ManyToManyField(
        'storage.Produto',
        related_name="produto"
    )

    def __str__(self):
        return self.produto_desc
Views.py

def CadastroProd(request):
    temp = 0


    lista_produto = Produto.objects.order_by('id')[:20]
    for i in lista_produto:
        temp += 1
    if request.method == 'POST':
        form = NovoProduto(request.POST)
        if form.is_valid():
            obj = Produto()
            obj.save(commit=False)

            obj.codigo = form.cleaned_data['codigo']
            obj.produto_desc = form.cleaned_data['produto_desc']
            obj.tipo = form.cleaned_data['tipo']
            # obj.estrutura = form.cleaned_data['estrutura']
            obj.save()

            return HttpResponseRedirect('/storage/produtos')

    lista_produto = Produto.objects.order_by('id')[:20]
    lista_pi = Produto.objects.filter(tipo='PI')
    lista_pa = Produto.objects.filter(tipo='PA')

    context = {'lista_produto': lista_produto,
               'temp': temp,
               'lista_pi': lista_pi, 'lista_pa': lista_pa,
               }

    return render(request, 'storage/cadproduto/cadproduto.html', context)

forms.py

class NovoProduto(forms.Form):
    codigo = forms.CharField(label='codigo', max_length=254)
    produto_desc = forms.CharField(label='produto_desc', max_length=100)
    tipo = forms.CharField(label='tipo', max_length=2)
    estrutura = forms.IntegerField()

索引


国际生产公司
{lista_pi%}
{{prod.produto_desc}}
{%endfor%}

地籍

我希望我可以获得产品的信息,以及组成它的产品的信息

您正在使用自己的自定义模板,因此使用getlist()方法获取所选选项列表,并使用set()方法保存多个字段,如下所示 此外,如果表单有效,则需要保存表单

if request.method == 'POST':
        form = NovoProduto(request.POST)
        estrutura = request.POST.getlist('estrutura')
        if form.is_valid():
            obj=form.save(commit=False)

            obj.codigo = form.cleaned_data['codigo']
            obj.produto_desc = form.cleaned_data['produto_desc']
            obj.tipo = form.cleaned_data['tipo']
            # obj.estrutura = form.cleaned_data['estrutura']
            obj.save()
            obj.estrutura.set(estrutura)
            return redirect....

您正在使用自己的自定义模板,因此使用getlist()方法获取selected choices列表,并使用set()方法保存manytomany字段,如下所示 此外,如果表单有效,则需要保存表单

if request.method == 'POST':
        form = NovoProduto(request.POST)
        estrutura = request.POST.getlist('estrutura')
        if form.is_valid():
            obj=form.save(commit=False)

            obj.codigo = form.cleaned_data['codigo']
            obj.produto_desc = form.cleaned_data['produto_desc']
            obj.tipo = form.cleaned_data['tipo']
            # obj.estrutura = form.cleaned_data['estrutura']
            obj.save()
            obj.estrutura.set(estrutura)
            return redirect....

在表单子类中,使用:

M2M字段似乎是一个自参考(除非您有两个名为
Produto
的型号),因此您可能希望从选择选项列表中排除当前产品

您可以在表单的构造函数中修改ModelMultipleEchoiceField的查询集:

    def __init__(*args, **kwargs):
        super().__init__(*args, **kwargs)
        if self.instance and self.instance.id:
            self.fields['estrutura'].queryset = Produto.objects.exclude(id=self.instance.id).order_by('id')[:20]

在表单子类中,使用:

M2M字段似乎是一个自参考(除非您有两个名为
Produto
的型号),因此您可能希望从选择选项列表中排除当前产品

您可以在表单的构造函数中修改ModelMultipleEchoiceField的查询集:

    def __init__(*args, **kwargs):
        super().__init__(*args, **kwargs)
        if self.instance and self.instance.id:
            self.fields['estrutura'].queryset = Produto.objects.exclude(id=self.instance.id).order_by('id')[:20]