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

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

新規登録して質問してみよう
ただいま回答率
85.35%
Django

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

Python

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

Q&A

解決済

1回答

1647閲覧

Djangoのformsetの値の方法

corse

総合スコア1

Django

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

Python

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

0グッド

0クリップ

投稿2020/10/06 09:44

Django初心者です。

formsetを使用して複数レコードの登録・修正を行おうとしています。
レコードの内容を調べて、内容によってWidgetを変更したいと思っています。

具体的には、レコード修正の際、承認されたレコード(approval=True)は変更したくないのでreadonly指定を付けたいのですが、widgetで指定する場合に読み込んだformsetの内容からデータを確認したいのですが、どうしたらいいかわかりません。

該当のソースコード

Python

1models.py 2 3class Test(models.Model): 4 BOOL_CHOICES = ((False, '未承認'), (True, '承認')) 5 6 id = models.AutoField(primary_key = True) 7 title = models.CharField(max_length = 200, verbose_name = 'タイトル') 8 point = models.IntegerField(verbose_name = '点数') 9 approval = models.BooleanField(choices=BOOL_CHOICES, verbose_name = '承認') 10 date = models.DateTimeField(default = timezone.now, verbose_name = '登録日付') 11 12 13 14 forms.py 15 16class TestForm(forms.ModelForm): 17 18 class Meta: 19 model = Test 20 fields = ('id', 'title', 'point', 'approval') 21 22 def __init__(self, *args, **kwargs): 23 super().__init__(*args, **kwargs) 24 25 for field in self.fields.values(): 26 27 field.widget.attrs['class'] = 'form-control' 28 29TestnFormSet = forms.modelformset_factory(model = Test, form = TestForm, can_delete = True, extra = 5, max_num = 5)

試したこと

formの__init__でフォームデータから値を抜き出せないかと思ったのですがエラーとなります。

Python

1 def __init__(self, *args, **kwargs): 2 super().__init__(*args, **kwargs) 3 4 self.field['approval'] # これだとCharfieldが返ってきます 5 self.field['approval'].value # これはエラーになります 6 for field in self.fields.values(): 7 8 field.widget.attrs['class'] = 'form-control'

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

多少強引かもしれませんが、Formクラスにて、
データを取得、中のフィールドの値を抜きだして条件判定するやり方はいかがでしょうか。

# forms.py from django import forms from .models import Test class TestForm(forms.ModelForm): class Meta: model = Test fields = ('id', 'title', 'point', 'approval') def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) for field in self.fields.values(): field.widget.attrs['class'] = 'form-control' # Modelへの実体にアクセス instance = getattr(self, 'instance', None) # データから承認フィールドの値を直接取得し条件判定を行います。 # 読み込みタイミングによってはinstanceがNoneの場合があるので、トラップしています。 if instance and instance.approval == True: # すべてのフォームを編集不可にします。 for fieldname in self.fields: self.fields[fieldname].widget.attrs['readonly'] = True

参考にしたサイト:
https://qiita.com/qtatsunishiura/items/a6cc11e025aca1c16ed1
https://stackoverflow.com/questions/324477/in-a-django-form-how-do-i-make-a-field-readonly-or-disabled-so-that-it-cannot
5h

投稿2020/10/06 15:39

編集2020/10/06 15:58
sfdust

総合スコア1137

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

corse

2020/10/06 23:54

instance = getattr(self, 'instance', None) で取り出す必要があるんですね。 助かりました。ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問