我有一些具有多对多关系的简单对象。 Django使用obj1_obj2表加入了它们,它在mysql中看起来像这样;
id | person_id | nationality_id
-----------------------------------
1 | 1 | 1
2 | 1 | 2
现在当我保存obj1(在其形式中将obj2显示为Multi-select)时,obj1_obj2表中的id增加甚至是我没有更改它们。例如,我在其表单上更改obj1的基本字符字段并保存它,并且连接表中的数据似乎被删除并重新保存,从而为条目提供新的ID。
事实上,我不需要改变任何事情我只需要保存表格并发生同样的事情。
我在视图中所做的就是form.save(),没什么特别的。这是正常的方式吗?
编辑:添加了模型,视图,表单
class Person(models.Model):
name = models.CharField()
birthdate = models.CharField()
nationality = models.ManyToMany(Nationality)
class Employee(Person):
employeeNum = models.CharField()
class FamilyMember(Person):
employee = models.ForeignKey(Employee)
relationship = models.CharField()
class Nationality(models.Model):
abbrev = models.CharField()
country = models.CharField()
class FamilyMemberDetailsForm(forms.ModelForm):
class Meta:
model = FamilyMemeber
exclude = ['employee']
def editFamilyMember(request, familyMember_id):
familyMember = get_object_404(FamilMember, familyMember_id)
if request.method == 'POST':
form = FamilyMemberDetailsForm(request.POST, instance=familyMember)
if form.is_valid():
form.save()
else:
form = FamilyMemberDetailsForm(instance=familyMember)
return render_to_response(editForm.html, {'form':form},
context_instance(RequestContext(request))
这是模型的简化版本,但保存员工或家庭成员的情况也是如此。我已经展示了FamilyMember,因为它就像我创建modelForm然后进行更改然后保存它一样简单。对于员工,我在国籍表格的 init 中进行了一些操作,主要用于演示,起初我认为正是这种操作导致了它,但正如我所说同样的事情发生了和FamilyMember一起,除了保存,我什么都不做。
国籍在表单上显示为带有列表的多选框,用户可以从列表中选择1个或更多。如果我只显示填充的表单,然后保存它而不更改任何内容,多对多表条目的ID更改。
我也更改了示例表标题。
谢谢,
安德鲁
答案 0 :(得分:2)
是的,在为具有ManyToManyField的对象保存表单时,删除appname_obj1_obj2中的任何现有行都是预期的行为。
你可以在django / db / models / fields / related.py中的ReverseManyRelatedObjectsDescriptor和ManyRelatedObjectsDescriptor中的add(**值)之前看到clear()。
弹出一个shell并亲自查看一下这些查询。这样的东西应该在原始sql中的INSERT之前显示DELETE。
from django.db import connection
fm = FamilyMember.objects.get(pk=1)
form = FamilyMemberDetailsForm(instance=fm)
data = form.initial
data['name'] = "z%s" % data['name']
form = FamilyMemberDetailsForm(data, instance=fm)
connection.queries = [] # clearing to limit the queries you have to look at
form.save()
for q in connection.queries:
print("%s\n" % q['sql'])