- 我有一个 Client 和 Groupe 模型。
- 一个客户可以是多个组的一部分。
- 客户 属于某个组的客户可以随时使用其组的免费租金,但只能使用一次。这就是中间模型 (ClientGroupe) 带来额外数据的地方。
现在,当我尝试保存 m2m 数据时,它就死了,并说我应该使用 ClientGroupe 管理器...所以缺少什么?
这是我的模型:
class Groupe(models.Model):
nom = models.CharField(max_length=1500, blank=True)
class Client(models.Model):
nom = models.CharField(max_length=450, blank=True)
prenom = models.CharField(max_length=450, blank=True)
groupes = models.ManyToManyField(Groupe, null = True, blank = True, through='ClientGroupe')
class ClientGroupe(models.Model):
client = models.ForeignKey(Client)
groupe = models.ForeignKey(Groupe)
dt = models.DateField(null=True, blank=True) # the date the client is using its group's free rental rate
class Meta:
db_table = u'clients_groupes'
这是我的观点:
def modifier(request, id):
client = Client.objects.get(id=id)
form = ClientForm(instance = client)
dict = {
"form": form
, "instance" : client
}
if request.method == "POST":
form = ClientForm(request.POST, instance = client)
if form.is_valid():
client_mod = form.save()
id = client_mod.id
return HttpResponseRedirect(
"/client/%(id)s/?err=success" % {"id" : id}
)
else:
return HttpResponseRedirect(
"/client/%(id)s/?err=warning" % {"id" : id}
)
return render_to_response(
"client/modifier.html"
, dict
, context_instance=RequestContext(request)
)
编辑:
这是 ClientForm 代码:
class ClientForm(ModelForm):
class Meta:
model = Client
编辑#2: 这是错误消息:
AttributeError at /client/445/
Cannot set values on a ManyToManyField which specifies an intermediary model. Use ClientGroupe's Manager instead.
Request Method: POST
Request URL: http://localhost/client/445/
Exception Type: AttributeError
Exception Value: Cannot set values on a ManyToManyField which specifies an intermediary model. Use ClientGroupe's Manager instead.
Exception Location: C:\Python25\lib\site-packages\django\db\models\fields\related.py in __set__, line 574
Python Executable: C:\xampp\apache\bin\apache.exe
Python Version: 2.5.2
最佳答案
如果您现在使用 save 方法,Django 将尝试使用管理器进行保存(Django 不允许这样做)。不幸的是,您想要的行为比默认情况下 ModelForm
的行为要复杂一些。你需要做的是创建一个formset。
首先,您需要更改 ClientForm
的选项,使其不显示 groupes
属性。
class ClientForm(ModelForm):
class Meta:
model = Client
exclude = ('groupes',)
接下来,您必须更改 View 以显示表单集:
from django.forms.models import inlineformset_factory
def modifier(request, id):
client = Client.objects.get(id=id)
form = ClientForm(instance = client)
# Create the formset class
GroupeFormset = inlineformset_factory(Client, Groupe)
# Create the formset
formset = GroupeFormset(instance = client)
dict = {
"form": form
, "formset" : formset
, "instance" : client
}
if request.method == "POST":
form = ClientForm(request.POST, instance = client)
formset = GroupeFormset(request.POST, instance = client)
if form.is_valid() and formset.is_valid():
client_mod = form.save()
formset.save()
id = client_mod.id
return HttpResponseRedirect(
"/client/%(id)s/?err=success" % {"id" : id}
)
else:
return HttpResponseRedirect(
"/client/%(id)s/?err=warning" % {"id" : id}
)
return render_to_response(
"client/modifier.html"
, dict
, context_instance=RequestContext(request)
)
显然,您还必须调整模板以呈现表单集。
如果您需要有关表单集的任何其他建议,请参阅以下文章:
关于python - 使 ModelForm 与 Django 中的中间模型的多对多关系工作的步骤是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/387686/