Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/django/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 通过ModelForm的关系设置Django M2M的值_Python_Django_Many To Many - Fatal编程技术网

Python 通过ModelForm的关系设置Django M2M的值

Python 通过ModelForm的关系设置Django M2M的值,python,django,many-to-many,Python,Django,Many To Many,我正在Django应用程序中处理一组产品/类别关系 一个产品可以属于任何类别,并且需要在该类别内订购,我正试图使用一个“through=”选项的多对多关系来实现这一点 当通过Ajax发出POST请求时,其形式为b'ordered\u products=4&ordered\u products=5',我在表单\uuu init\uuuuuuu调用之后收到一个错误,即“5不是可用选项之一”,其中5是OrderedCategoryManagedProduct对象的有效id models.py view

我正在Django应用程序中处理一组产品/类别关系

一个产品可以属于任何类别,并且需要在该类别内订购,我正试图使用一个“through=”选项的多对多关系来实现这一点

当通过Ajax发出POST请求时,其形式为
b'ordered\u products=4&ordered\u products=5'
,我在表单
\uuu init\uuuuuuu
调用之后收到一个错误,即“5不是可用选项之一”,其中5是
OrderedCategoryManagedProduct
对象的有效id

models.py views.py 非常感谢#django IRC频道在这方面的帮助,如果有人遇到同样的问题,正确的代码如下:

class ReorderCategoryProductsForm(forms.ModelForm):
    ordered_products = OrderedModelMultipleChoiceField(
        queryset=OrderedCategoryManagedProduct.objects.all()
    )

    class Meta:
        model = Category
        fields = ["id"]

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        if self.instance:
            self.fields["ordered_products"].queryset = self.instance.cm_products.all()
        pass

    def save(self):
        for sort_order, ocmp in enumerate(self.cleaned_data["ordered_products"]):
            ocmp.sort_order = sort_order
            ocmp.save()
        return self.instance

您能显示完整的错误跟踪吗?注意(与错误无关):您没有正确保存,
product.save()
不会保存您试图更改的
category\u management
实例。请尝试将至少
pk
添加到
fields()
@OlegRusskin Done,否change@dirkgroten修正了保存方法(我认为)没有变化。它不会给我完整的堆栈跟踪,因为错误只是一些原始HTML,将附加到返回的json。
# POST = <QueryDict: {'ordered_products': [5, 4]}>
@staff_member_required
@permission_required("menu.manage_menus")
def ajax_reorder_menu_items(request, category_pk):
    category = get_object_or_404(Category, pk=category_pk)
    form = ReorderCategoryProductsForm(request.POST, instance=category)
    status = 200
    ctx = {}
    if form.is_valid():
        form.save()
    elif form.errors:
        status = 400
        ctx = {"error": form.errors}
    return JsonResponse(ctx, status=status)
class ReorderCategoryProductsForm(forms.ModelForm):
    ordered_products = OrderedModelMultipleChoiceField(
        queryset=OrderedCategoryManagedProduct.objects.none()
    )

    class Meta:
        model = Category
        fields = ["id"]

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        if self.instance:
            self.fields["ordered_products"].queryset = self.instance.cm_products.all()
        pass

    def save(self):
        for sort_order, category in enumerate(self.cleaned_data["ordered_products"]):
            category.cm_products.sort_order = sort_order
            category.save()
        return self.instance


class OrderedModelMultipleChoiceField(forms.ModelMultipleChoiceField):
    def clean(self, value):
        qs = super().clean(value)
        keys = list(map(int, value))
        return sorted(qs, key=lambda v: keys.index(v.pk))
class ReorderCategoryProductsForm(forms.ModelForm):
    ordered_products = OrderedModelMultipleChoiceField(
        queryset=OrderedCategoryManagedProduct.objects.all()
    )

    class Meta:
        model = Category
        fields = ["id"]

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        if self.instance:
            self.fields["ordered_products"].queryset = self.instance.cm_products.all()
        pass

    def save(self):
        for sort_order, ocmp in enumerate(self.cleaned_data["ordered_products"]):
            ocmp.sort_order = sort_order
            ocmp.save()
        return self.instance