2017-03-28 12 views
1

Django 1.10では、フォームのレコードを編集するために、データベースのレコードを使用してテンプレート内にModelFormをあらかじめ準備しています。ただし、フォームのHTMLをレンダリングする場合は、id(またはpk)のフィールドは表示されません。 idを隠した<入力>タグに入れたいので、フォームが送信されたときにフォームが編集するレコードをバックエンドに送信するときにそのフォームが送信されます。私のWebアプリケーションはURLにidを持っていません。 、私は名前'Alice'と電話'212-555-5555'と1件のmymodelというレコードを追加したデータベースで私のDjangoテンプレートは、ModelFormのidフィールドまたはpkフィールドをレンダリングしないのはなぜですか?

from django.db import models 

class MyModel(models.Model): 
    name = models.CharField(max_length=50) 
    phone = models.CharField(max_length=50) 

は、ここに私のmodels.pyです。 ID /主キーは1です。ここで

は私forms.pyです:ここでは

from django import forms 
from . import models 

class TestForm(forms.ModelForm): 
    class Meta: 
     model = models.MyModel 
     fields = ['id', 'name', 'phone'] 

は私のviews.pyである:ここでは

from django.shortcuts import render 
from . import forms, models 

def test_page(request): 
    m = models.MyModel.objects.get(name='Alice') 
    prepopulatedForm = forms.TestForm(instance=m) 
    return render(request, 'testproject/test_template.html', {'form': prepopulatedForm}) 

は私test_template.htmlです:

<h1>Test Page</h1> 
{{ form }} 

これは、フォームをレンダリングページには、'Alice''212-555-5555'が事前に設定されています。

<h1>Test Page</h1> 
<tr><th><label for="id_name">Name:</label></th><td><input id="id_name" maxlength="50" name="name" type="text" value="Alice" required /></td></tr> 
<tr><th><label for="id_phone">Phone:</label></th><td><input id="id_phone" maxlength="50" name="phone" type="text" value="212-555-5555" required /></td></tr> 

私の質問は、ID /プライマリキーの列がこのフォームに表示されないのはなぜですか?

<h1>Test Page</h1> 

<input id="id_name" maxlength="50" name="name" type="text" value="Alice" required /> 
<input id="id_phone" maxlength="50" name="phone" type="text" value="212-555-5555" required /> 

私はpython manage.py shellを実行しているから見ることができます:

<h1>Test Page</h1> 
{{ form.id }} 
{{ form.name }} 
{{ form.phone }} 

これはID <入力>があるべき空白をレンダリング:私はどちらかのテンプレートのためにこれを使用するときに私はそれをレンダリングするために取得することはできません発生しないfields['id', 'name', 'phone']に設定forms.pyで

>>> from testproject import models 
>>> m = models.MyModel.objects.get(name='Alice') 
>>> m.id 
1 

、:レコードが存在し、実際にあることをyエラーもありません。['pk', 'name', 'phone']もありません。私は意図的['NOT_REAL_FIELD', 'name', 'phone']のような存在しないフィールド名を追加する場合は、その後、python manage.py runserverはエラーを生成します。

File "C:\Users\Al\venvs\tas_env\lib\site-packages\django\forms\models.py", line 257, in __new__ 
    raise FieldError(message) 
django.core.exceptions.FieldError: Unknown field(s) (NOT_REAL_FIELD) specified for MyModel 

だから私は'id'/'pk'はのModelFormに置くために正当なフィールドでなければならないことを知っています。

私のDjangoテンプレートがModelFormのidフィールドまたはpkフィールドをレンダリングしないのはなぜですか?

最終的には、データベースのレコードを編集できるように、主キーを隠し入力としてフォームに含めたいと思います。また、ModelAdminについては、管理者パネルではなくユーザーが表示できるテンプレートに表示しようとしているので、私は気にしません。 pkは読み取り専用です。それは単にテンプレートでレンダリングする必要があります。

+0

なぜidフィールドを編集可能にしますか? Djangoでは、通常の方法はidをURLに含めることです。 '/ mymodel/ /'を呼び出し、ビュー内で編集するオブジェクトを取得します。 'MyModel.objects.get(pk = pk)'。 – Alasdair

+0

pkを隠した<入力>タグに入れたいので、フォームが送信されたときにフォームが編集するレコードを知っているバックエンドを送信します。私のURLは<ユーザーのもの>のpkを持っていませんが、むしろ "/ /<ユーザーのもの>"です。この2ビットの情報を使ってレコードを取得する必要がありますか? –

答えて

1

idフィールドは自動的にeditable=Falseです。これはデフォルトではどのモデルフォームにも表示されません。

idを隠しフィールドに入れる必要はありません。オブジェクトを編集するためにURLに行き、そのURLがフォームを表示する場合、同じURLにサブミットする必要があります。この場合、URLにはまだIDがあります。

+0

私はこれがそれだとは思わない。 'name'または' phone'フィールドに 'editable = False'を設定すると、' python manage.py runserver'を実行するとエラーメッセージが表示されます: 'django.core.exceptions.FieldError: 'phone '編集できないフィールドであるため、MyModelモデルフォームに指定することはできません。' 'id'または' pk'フィールドでこのエラーが発生しません。 –

+0

私のWebアプリケーションの場合、私はURLに主キーを使用していません。 URLは/ /で、ユーザーのIDを使用するのではなく、URLから取得することはできません。 –

2

{{ form.initial.id }}を使用してIDにアクセスするのはどうですか?

ModelFormメタクラスを見ても分かるように、form.initialは、フォームプロパティの作成とは少し異なります(たとえば、form.nameまたはform.phone)。だから基本的には、ジャンゴのメタクラスの雑草にありますmagic ...

もう少し具体的です。フォームを作成するときに渡されるモデルインスタンスからデータを引き出すためにmodel_to_dictが呼び出されますが、fields_for_modelが呼び出されてからフォームインスタンスにクラス属性としてアクセス可能なモデルフィールドがあるまではありません。私はidが何らかの形で考慮されているフィールドから除外されていると思います。fields_for_modelあなたが参照した編集不可能なフィールド例外もここで上げられているようです。

+0

これは動作します!奇妙なことに、 '{{form.initial.pk}}'は空白です。これは私の元の質問に答えることはできませんが、私の現在の回避策よりも若干良い回避策です。 '.initial'が何であるかを調べるにはどうすればよいですか?それは "動的初期値"に関連しているのですか、それとも別の概念ですか?私はテンプレートでPKをレンダリングするためのベストプラクティスを知りたいと思います。 –

+0

連絡先を追加しました。私は、ModelFormのソースコード、特にメタクラスのセクションを見ることで大まかな感覚を得ることができました。 – scuerda

関連する問題