質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.52%

  • Python

    7953questions

    Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

  • Django

    1049questions

    DjangoはPythonで書かれた、オープンソースウェブアプリケーションのフレームワークです。複雑なデータベースを扱うウェブサイトを開発する際に必要な労力を減らす為にデザインされました。

【django】記事ごとにパスワードを設定したい

解決済

回答 1

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 297
退会済みユーザー

退会済みユーザー

前提・実現したいこと

表記の通り、記事ごとにパスワードを設定し、そのパスワードを知っている人しか編集できない、というよくある仕組みを作りたいと考えております。
現在編集中のコードをご確認下さい。

#models.py

class practice(models.Model):
    text1 = models.TextField()
    password = models.CharField(max_length=30)


テキストエリアと、パスワードをフィールドとして持っております。

♯forms.py

class PraForm(forms.ModelForm):
    class Meta:
        model = practice
        fields = ('text1','password')

    def __init__(self, *args, **kwargs):
        practice_id = kwargs.pop('practice_id')
        super(PraForm, self).__init__(*args, **kwargs)

        def clean_password(self):
            password = self.cleaned_data['password']
            aaa = practice.objects.get(id = practice_id)
            if password != aaa.password:
                raise forms.ValidationError('パスワードが違います')
            return password


ここの仕組み作りは下記点において苦しんでおります。。。
・CBV→modelformへのID(pk)の渡し方 ※解決しました。
・idに紐づいたパスワードとの照合方法
入力されたpasswordとDBから引っ張ってきたpasswordがマッチすれば
form_validになるというイメージです。

#views.py

def top(request):
    return render(request, 'top.html')

class DataView(FormMixin, generic.DetailView):
    model = practice
    form_class = PraForm
    template_name = 'practice_detail.html'

    def get_form_kwargs(self):
        kwargs = super(DataView, self).get_form_kwargs()
        kwargs['practice_id'] = self.kwargs['pk']
        return kwargs

    def post(self, request, *args, **kwargs):
        form = self.get_form()
        if form.is_valid():
            return self.form_valid(form)
        else:
            return self.form_invalid(form)

    def form_valid(self, form):
        practice_pk = self.kwargs['pk']
        return redirect('pra1:dataview', pk=practice_pk)

    def form_invalid(self, form):
        return redirect('pra1:top')


先ほどのformの照合で、form_validになればリダイレクト先の編集ページに飛ばそうと思っております。(このコードは自身へのリダイレクトになっております。)

発生している問題・エラーメッセージ

※このエラーは解決したので削除します。

恐らくforms.pyのid = idの部分が問題なのだろうと思います。

如何にして、formにparameterを渡していくか、
そしてその先のvalidationに関してもコードのご教示を頂ければ幸いです。
宜しくお願い致します。

追記

パラメーターのpassにはどうやら成功したようです。
上記のコードを編集し直しました。
しかしリダイレクト先は、form_invalidの方になってしまいます。
forms.pyのclean_passwordが上手く動作していないようですが、DBに保存された既存のpasswordといかに照合すればよいでしょうか。
改めてご教示のほど宜しくお願い致します。

補足

ちなみにですがforms.pyを

#forms.py

class PraForm(forms.ModelForm):
    class Meta:
        model = practice
        fields = ('text1','password')

    def __init__(self, *args, **kwargs):
        practice_id = kwargs.pop('practice_id')
        super(PraForm, self).__init__(*args, **kwargs)

    def clean_password(self):
        password = self.cleaned_data['password']
        aaa = practice.objects.get(id = practice_id)
        if password != aaa.password:
            raise forms.ValidationError('パスワードが違います')
        return password


のように書くと
ERROR:name 'practice_id' is not defined
のように出てしまいますが、このエラーの解決が答えにつながる気もしております。
上の方で書いたforms.pyはnot definedが出ていたのでinitの中に入れてみたという挑戦の軌跡となっております。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

checkベストアンサー

0

オブジェクトの中でmethodをまたがって値をやり取りしたい時はインスタンス変数に値を入れないと
その値はmethod内の処理が終了すると参照できなくなります。

def __init__(self, *args, **kwargs):
    self.practice_id = kwargs.pop('practice_id')
    super(PraForm, self).__init__(*args, **kwargs)

def clean_password(self):
    password = self.cleaned_data['password']
    aaa = practice.objects.get(id = self.practice_id)
    if password != aaa.password:
        raise forms.ValidationError('パスワードが違います')
    return password

上のようにmethodをまたがってやり取りしたい値はself.practice_idと保存しましょう。
他の箇所が原因かもしれませんが、これで一度試してみてください。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/09/16 10:26

    ご回答頂きまして有難うございました!
    ご指摘頂いたコードにて、【is not defined】のエラーはクリアできたようですが、
    やはりリダイレクト先は、form_invalidのままでした。。
    clean_passwordの書き方がおかしいのでしょうか?

    キャンセル

  • 2017/09/16 14:27

    あまりこの書き方で書いたことがないので、参考にしたサイトとかありましたらURL教えていただけますか?

    キャンセル

  • 2017/09/16 18:13

    ベタではありますが、djangoのチュートリアルや、
    https://docs.djangoproject.com/ja/1.11/ref/forms/validation/

    こういったサイトを参考にしております。
    http://python.keicode.com/django/form-validation.php

    http://hateda.hatenadiary.jp/entry/django-form-and-field-validation

    何度も有り難うございます。
    何卒宜しくお願い致しますm(_ _)m

    キャンセル

  • 2017/09/16 22:00

    連投で申し訳ございません。
    そもそもform_validにならないのはformの書き方が悪かったようです。
    (post送信の際にrequiredフィールドを送信していなかったため、is_validがFalseになり続けていたようです。)
    modelformをrequired=Falseで上書きしたところ上手く動作致しました。
    それによりまた新たな問題が生じたのですが、長くなるので質問は分けさせて頂きます。

    兎に角、is not definedを解決頂き誠に有難うございました。
    ベストアンサーに選ばせて頂きます。

    キャンセル

  • 2017/09/17 06:28

    おーいわれてみたらformの書き方あまりよくなかったかもですね。

    自己解決できたみたいでよかったです!お疲れ様でした!

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.52%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る

  • Python

    7953questions

    Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

  • Django

    1049questions

    DjangoはPythonで書かれた、オープンソースウェブアプリケーションのフレームワークです。複雑なデータベースを扱うウェブサイトを開発する際に必要な労力を減らす為にデザインされました。