4

現在ログインしているユーザーに基づいてメッセージの発信者を設定するメッセージング システムに取り組んでいます。

class Message(models.Model):
    originator = models.ForeignKey(User, related_name='+')
    destination = models.ForeignKey(User, related_name='+')
    subject = models.CharField(max_length=100)
    content = models.TextField()

これを表すために ModelForm と CreateView を使用します。

class MessageForm(forms.ModelForm):

    class Meta:
        model = Message
        fields = ('destination', 'subject', 'content')

したがって、このフォームを保存する前にoriginator、現在ログインしているユーザーに設定する必要があります。ここでモデルのメソッドをオーバーライドするのは適切ではないと思うsaveので、フォームのsaveメソッドでオーバーライドするつもりでしたが、リクエスト変数にアクセスできません。別の CreateView 投稿では、get_form_kwargsメソッドをオーバーライドすることをお勧めしました。

class MyFormView(FormView):
    def get_form_kwargs(self):
        # pass "user" keyword argument with the current user to your form
        kwargs = super(MyFormView, self).get_form_kwargs()
        kwargs['user'] = self.request.user
        return kwargs

userただし、ModelForm はカスタム引数を受け入れないため、実際には kwarg を ModelFormに渡すことができないため、これは機能しません。

originatorユーザー情報で変数を更新する最良の (最もクリーンで実用的な) 方法は何ですか?

4

1 に答える 1

3

yuji-tomita-tomitaとのディスカッションで、彼は次のことを提案しました。

最初の方法はuser、フォームに kwarg を送信する彼の元のコードに依存していget_form_kwargsます。次に、フォーム モデルを次のように変更する必要があります。

class MyModelForm(forms.ModelForm):

    def __init__(self, *args, **kwargs):
        self.user = self.kwargs.pop('user', None)
        super(MyModelForm, self).__init__(*args, **kwargs)

このようにして、元の__init__関数は期待どおりの引数を取得します。

しかし、彼が提案した好ましい方法は次のとおりです。

class MyView(CreateView):

     def form_valid(self, form):
          obj = form.save(commit=False)
          obj.user = self.request.user
          obj.save()
          return super(MyView, self).form_valid(form)

これは本当にうまくいきます。form.save(commit=False)メソッドが実行されると、変数に返されるモデルの同じインスタンスがフォーム オブジェクトに取り込まれself.instanceますobjobj実行して更新しobj.user = self.request.userて保存すると、formオブジェクトはこのまったく同じオブジェクトへの参照を持っているため、formここのオブジェクトはすでに完成しています。の元のform_validメソッドに渡すとCreateView、すべてのデータが含まれており、データベースに正常に挿入されます。

誰かがこれを行う別の方法を持っている場合、私はそれについて聞きたいです!

于 2013-01-18T01:17:36.397 に答える