python - 使 ModelForm 与 Django 中的中间模型的多对多关系工作的步骤是什么?

标签 python django django-models django-templates django-forms

  • 我有一个 ClientGroupe 模型。
  • 一个客户可以是多个的一部分。
  • 客户 属于某个组的客户可以随时使用其组的免费租金,但只能使用一次。这就是中间模型 (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)
    )

显然,您还必须调整模板以呈现表单集。

如果您需要有关表单集的任何其他建议,请参阅以下文章:

Model formsets
Formsets

关于python - 使 ModelForm 与 Django 中的中间模型的多对多关系工作的步骤是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/387686/

相关文章:

python - [字符串变量]>打印特殊字符

Python 失去对子进程的控制?

python - 无法使用唯一的第一个键确定性地更新嵌套字典

python - Django 全文搜索不匹配部分单词

django: sqlite3.OperationalError: 没有这样的表

python - 是什么导致 python 列表的(大)大小?

python - Django 1.6 : MySQL ERROR 1049 (42000): Unknown database

python - 在 Django 中创建通用 View

django - 从 django View 获取媒体文件夹的绝对路径

django rest api - 将用户添加到关键字模型