Django: как сделать стандартную форму ввода для условной вставки ИЛИ обновления записей типа "многие-ко-многим"?

Я пытаюсь найти способ обновления или вставки новых записей типа "многие-ко-многим" из Product в Order через промежуточную модель ProductOrder. Я хочу иметь стандартную форму со всеми Products и соответствующими количествами poQty. Стандартная форма (предполагается, что всего в ней будет 4 продукта) используется для обновления существующих записей Order. Если заказ имеет 2 Products, связанных с ним, форма должна:

  1. включите дополнительные продукты, если poQty>0
  2. изменить существующие продукты, если poQty изменился
  3. ничего не делать, если несуществующие Products остаются стандартными poQty=0

В настоящее время я получаю следующее сообщение об ошибке при попытке отправить форму:

 {'id': ['Select a valid choice. That choice is not one of the available choices.']}, 
{'id': ['Select a valid choice. That choice is not one of the available choices.']}, 
{'id': ['Select a valid choice. That choice is not one of the available choices.']}]

Буду признателен за помощь в этом вопросе... СПАСИБО !

Дополнительные сведения:

models.py

class ProductClass(models.Model):
    classDescription = models.CharField(max_length=255, verbose_name='Type', unique=True, null=True)
    classPrint = models.BooleanField(default=True, verbose_name='Print?')

    class Meta:
        verbose_name_plural = 'Product Classes'

    def __str__(self):
        return self.classDescription
    
class Product(models.Model):
    prodclassQuery = models.ForeignKey(ProductClass, on_delete=models.PROTECT, verbose_name='Product Class', default=1)
    prodDescription = models.CharField(max_length=255, verbose_name='Product')
    prodPrice = models.DecimalField(max_digits=6, decimal_places=2, verbose_name='Price')

    class Meta:
        ordering = ['prodclassQuery', 'prodDescription']

    def __str__(self):
        return self.prodDescription

class Menu(models.Model):
    menuActive = models.BooleanField(verbose_name='Active?', default=False)
    menuDescription = models.CharField(max_length=255, verbose_name='Menu')
    prodQuery = models.ManyToManyField(Product, verbose_name='Product')
    
    class Meta:
        ordering = ['menuDescription', ]
    
    def __str__(self):
        return self.menuDescription
    
class Order(models.Model):
    orderDtOpen = models.DateTimeField(auto_now_add=True)
    orderDtClose = models.DateTimeField(auto_now=True)
    orderOpen = models.BooleanField(default=True, verbose_name='Open?')
    orderTable = models.CharField(max_length=25, verbose_name='Table')
    menuQuery = models.ForeignKey(Menu, on_delete=models.PROTECT, verbose_name='Menu', default=1)
    prodQuery = models.ManyToManyField(Product, through='ProductOrder')
    
class ProductOrder(models.Model):
    poOrder = models.ForeignKey(Order, on_delete=models.CASCADE, verbose_name='Order', default=1)
    prodQuery = models.ForeignKey(Product, on_delete=models.CASCADE, verbose_name='Product', default=1)
    poQty = models.PositiveIntegerField(default=0, verbose_name='Quantity')

    class Meta:
        constraints = [
            models.UniqueConstraint(fields=('poOrder', 'prodQuery'), name='once_per_product_order')
        ]

forms.py

class OrderForm(ModelForm):
    class Meta:
        model = Order
        fields = ['orderOpen', 'orderTable', 'menuQuery',]

    def __init__(self, *args, **kwargs):
        super(OrderForm, self).__init__(*args, **kwargs)
        self.fields['menuQuery'].queryset = Menu.objects.filter(menuActive=True)

class ProductOrderForm(ModelForm):
    filtered_products = None

    class Meta:
        model = ProductOrder
        fields = ['prodQuery', 'poQty',]
        widgets = {'prodQuery': TextInput}

    def __init__(self, *args, **kwargs):
        super(ProductOrderForm, self).__init__(*args, **kwargs)
        self.filtered_products = Product.objects.filter(menu__prodQuery = self.instance.prodQuery)
        self.fields['prodQuery'].queryset = self.filtered_products

    def save(self, commit=True):
        print('*function save*')
        data = super(ProductOrderForm, self).save(commit=False)
        if data.poQty > 0 and commit:
            data.save()
        return data

views.py

def create_order(request):
    form = OrderForm(request.POST or None, request.FILES or None)
    filtered_products = ProductOrderForm()
    ProductOrderFormset = inlineformset_factory(Order, Order.prodQuery.through, form = ProductOrderForm, 
                                                extra = len(filtered_products.filtered_products),
                                                can_delete = False)
    if request.POST and form.is_valid():
        order = form.save(commit=False)
        formset = ProductOrderFormset(request.POST, instance=order)
        if formset.is_valid():
            try:  
                order.save()
                formset.save()
                return redirect('/orders')
            except:
                pass
    else:
        formset = ProductOrderFormset(request.POST or None, instance=Order(), 
                                      initial=[{'prodQuery': prod.id} for prod in filtered_products.filtered_products],)
    context = {
        'form': form, 
        'formset': formset,
    }
    return render(request,'create_order.html', context)
Вернуться на верх