我使用基于Django类的通用视图。在我的models.py中,我有一个名为MyModel的模型,其中包含多对多字段m2m。我有多组用户可以编辑m2m字段。每组用户只能看到并将其部分添加到字段中 - 使用get_form设置他们在m2m字段中可以看到的内容。我遇到的问题是,当一个用户输入他的记录时,它将删除m2m字段中的初始记录。我需要以某种方式从m2m字段获取初始值保存它们,然后在提交表单时将它们添加到新的值。这是我的views.py:
class MyModelUpdate(UpdateView):
model = MyModel
fields = ['m2m']
def get_initial(self):
return initials
def get_form(self, form_class=None):
form = super(MyModelUpdate, self).get_form(form_class)
form.fields["m2m"].queryset = DiffModel.objects.filter(user = self.request.user)
return form
def form_valid(self, form):
form.instance.m2m.add( ??? add the initial values)
return super(MyModelUpdate, self).form_valid(form)
def get_success_url(self):
...
答案 0 :(得分:0)
views.py:
from itertools import chain
from .forms import MyForm,
def MyModelUpdate(request, pk):
template_name = 'mytemplate.html'
instance = MyModel.objects.get(pk = pk)
instance_m2m = instance.m2m.exclude(user=request.user)
if request.method == "GET":
form = MyForm(instance=instance, user=request.user)
return render(request, template_name, {'form':form})
else:
form = MyForm(request.POST or None, instance=instance, user=request.user)
if form.is_valid():
post = form.save(commit=False)
post.m2m = chain(form.cleaned_data['m2m'], instance_m2m)
post.save()
return redirect(...)
forms.py:
from django import forms
from .models import MyModel
class MyForm(forms.ModelForm):
class Meta:
model = MyModel
fields = ['m2m']
def __init__(self, *args, **kwargs):
current_user = kwargs.pop('user')
super(MyForm, self).__init__(*args, **kwargs)
self.fields['m2m'].queryset = self.fields['m2m'].queryset.filter(user=current_user)
答案 1 :(得分:0)
我添加此答案是为了简化此类问题的解释,也是因为OP在他的解决方案中从UpdateView切换到基于函数的视图,这可能不是某些用户正在寻找的。< / p>
如果将UpdateView用于具有ManyToMany字段的模型,但由于只希望将此数据保留下来而没有向用户显示,则在保存表单后,所有m2m值都将被删除。 / p>
这显然是因为Django希望将此字段包含在表单中,并且不包含此字段与将其发送为空相同,因此,它告诉Django删除所有ManyToMany关系。
在这种简单情况下,您无需定义form_valid然后再检索原始值,依此类推,您只需要告诉Django不要使用此字段即可。
因此,如果您查看的话:
class ProjectFormView(generic.UpdateView):
model = Project
form_class = ProjectForm
template_name = 'project.html'
在您的表单中,排除m2m字段:
class ProjectForm(forms.ModelForm):
class Meta:
model = Project
fields = '__all__'
exclude = ['many_to_many_field']