31
  • クライアントグループモデルがあります。
  • クライアントは複数のグループの一部になることができます。
  • グループに所属しているクライアントは、グループの無料レンタル料金をいつでも1回だけ使用できます。そこで、中間モデル(ClientGroupe)がその追加データを使用します。

今のところ、m2mデータを保存しようとすると、データが停止し、ClientGroupe Managerを使用する必要があると表示されます...何が欠けていますか?

これが私のモデルです:

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
4

5 に答える 5

18

現在 save メソッドを使用すると、Django はマネージャーを使用して保存しようとします (これは Django では許可されていません)。ModelForm残念ながら、あなたが望む振る舞いは、デフォルトよりも少しトリッキーです。あなたがする必要があるのは、formsetを作成することです。

まず、属性ClientFormを表示しないようにオプションを変更する必要があります。groupes

class ClientForm(ModelForm):
    class Meta:
        model = Client
        exclude = ('groupes',)

次に、ビューを変更してフォームセットを表示する必要があります。

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)
    )

そして明らかに、フォームセットをレンダリングするには、テンプレートも調整する必要があります。

フォームセットに関するその他のアドバイスが必要な場合は、次の記事を参照してください。

モデル フォーム
セット

于 2009-05-31T15:27:30.123 に答える
11
…
if form.is_valid():
    client_mod = form.save(commit=False)
    client_mod.save()
    for groupe in form.cleaned_data.get('groupes'):
        clientgroupe = ClientGroupe(client=client_mod, groupe=groupe)
        clientgroupe.save()
    …
于 2010-10-07T14:41:20.297 に答える
4

ManyToMany フィールドを Client モデルから削除するか、フォームから慎重に除外する必要があります。残念ながら、ManyToMany フィールドのデフォルト ウィジェットは、ClientGroupe モデルに適切に入力できません (欠落しているフィールド dt が autonow=True に設定されていたとしても)。これは、別のフォームに分割するか、ビューで処理する必要があるものです。

于 2009-02-18T03:15:42.767 に答える
0

フォームを保存するときは、Clientオブジェクトを保存します。ここで、クライアントをグループに割り当てる場合は、次のようにする必要があります。

clientgroupe = ClientGroupe.objects.create(client=client_instance, groupe=groupe_instance, dt=datetime.datetime.now())

ここで、client_instanceとgroupe_instanceは、クライアントとグループのオブジェクトです。

于 2009-01-25T21:56:02.757 に答える