Python 通过ModelForm的关系设置Django M2M的值
我正在Django应用程序中处理一组产品/类别关系 一个产品可以属于任何类别,并且需要在该类别内订购,我正试图使用一个“through=”选项的多对多关系来实现这一点 当通过Ajax发出POST请求时,其形式为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
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