2011-08-15 6 views
1

私はDjangoの面白い状況に直面しています。私は誰かがこれに対する解決策を見たり、少なくとも私にヒントを与えることを期待していました。Django ModelFormモデルを汎用化するには?

私はModelFormモデルを一般的なものにしようとしています。私はこれが何かであるべきかどうかはわかりませんが、ここでそれは行きます。

これは正常に動作します:

モデル

# settings.py 
SPECIES = (
    ('TIG', 'Tiger'), 
    ('SHR', 'Shark'), 
) 

# urls.py 
from django.conf.urls.defaults import patterns, include, url 
urlpatterns = patterns('species.views', 
    url(r'^add/$', 'add_animal', name='add_animal'), 
) 

に動物モデルとその2人の子供が動物のオブジェクトを作成するためのURLを参照してタプルを

# models.py 
from django.db import models 
from django.conf import settings 

class Animal(models.Model): 
    name = models.CharField(max_length=100) 
    nickname = models.CharField(max_length=100) 
    species = models.CharField(max_length=3, choices=settings.SPECIES) 

class Tiger(Animal): 
    fangs_size = models.IntegerField() 

class Shark(Animal): 
    color = models.CharField(max_length=20) 

権利モデルは、GETパラメータを介して選択される形態

を表示するビュー。

# views.py 
def add_animal(request): 
    if request.method == "GET": 
     if request.GET['model_name']: 
      model_name = request.GET['model_name'] 
    else: 
     model_name = 'Animal' 

    print "Model name is: %s" % model_name 

    model = get_model("species", model_name) 
    form = AnimalForm(model=model) 

    return create_object(
     request, 
     model=model, 
     post_save_redirect=reverse('index'), 
     template_name='species/my_form.html', 
    ) 

テンプレート

# my_form.html 
<!doctype html> 
<html> 
    <head> 
     <title>Adding an animal</title> 
    </head> 
    <body> 
     <h1>Add an animal to the farm</h1> 
     <form> 
      {% csrf_token %} 
      {{ form.as_p }} 
      <input type="submit" value="Submit" /> 
     </form> 
    </body> 
</html> 

私が訪問したとき/追加しますか?MODEL_NAME =虎、私が表示された右のフォームを取得します。

ここで、ニックネームフィールドを非表示にしたいとします。私はカスタムのModelFormを使用する必要があります。適切なモデルでそれをインスタンス化する方法は?それが私の問題です。

ここにフォームがありますか?

# forms.py 
from species.models import Animal 
from django import forms 

class AnimalForm(forms.ModelForm): 

    class Meta: 
     model = Animal 

    def __init__(self, *args, **kwargs): 
     model = kwargs.pop('model') 
     super(AnimalForm, self).__init__(*args, **kwargs) 
     self.Meta.model = model 

ビューは次のようになります。

# views.py 
... 
model = get_model("species", model_name) 
form = AnimalForm(model=model) 

return create_object(
    request, 
    # model=model,   # Need for customization 
    # form_class=AnimalForm, # With the class name, how to pass the argument? 
    form_class=form,   # Not sure this can be done, I get this error: 'AnimalForm' object is not callable 
    post_save_redirect=reverse('index'), 
    template_name='species/my_form.html', 
) 
... 

私の目標は、後に動物から継承する新しいモデルを作成し、種のタプルに追加して行うことができるようにすることです。これは達成できますか?

ありがとうございました!

答えて

5

おそらくdjango.forms.models.modelform_factoryを使用したいと思うかもしれません - そのパラメータの中でモデルクラスとexcludeタプルをとります。ビューでこれを使用すると、フォームクラスを動的に作成できます。

form_class = modelform_factory(model, exclude=('nickname',)) 
+0

ダニエルに感謝します。 –

関連する問題