Djangoでは、どのようにしてDjangoのupdate_object汎用ビューを使用して、継承されたモデルのフォームを編集できますか?
-
03-07-2019 - |
質問
Djangoでは、次のようなアプリケーション動物からの抜粋があります:
A animals / models.py と:
from django.db import models
from django.contrib.contenttypes.models import ContentType
class Animal(models.Model):
content_type = models.ForeignKey(ContentType,editable=False,null=True)
name = models.CharField()
class Dog(Animal):
is_lucky = models.BooleanField()
class Cat(Animal):
lives_left = models.IntegerField()
および animals / urls.py :
from django.conf.urls.default import *
from animals.models import Animal, Dog, Cat
dict = { 'model' : Animal }
urlpatterns = (
url(r'^edit/(?P<object_id>\d+)
一般的なビューを使用して、同じフォームを使用して犬や猫を編集するにはどうすればよいですか
つまり animals / animal_form.html に渡される form オブジェクトはAnimalであるため、派生クラスDogおよびCatの詳細は含まれません。 Djangoが子クラスのフォームを animal / animals_form.html に自動的に渡すようにするにはどうすればよいですか?
偶然、私は Djangosnippets#1031 をContentType管理に使用しています。派生クラスを返す as_leaf_class という名前のメソッドがあります。
明らかに、派生クラスごとにフォームを作成できますが、それは非常に多くの不必要な重複です(テンプレートはすべて汎用であるため、本質的に{{form.as_p}})。
ちなみに、Animalはおそらく同じ問題を持ついくつかの無関係な基底クラスの1つであると想定するのが最善であるため、理想的な解決策は一般的です。
助けてくれてありがとう。
, 'create_update.update_object', dict),
)
一般的なビューを使用して、同じフォームを使用して犬や猫を編集するにはどうすればよいですか
つまり animals / animal_form.html に渡される form オブジェクトはAnimalであるため、派生クラスDogおよびCatの詳細は含まれません。 Djangoが子クラスのフォームを animal / animals_form.html に自動的に渡すようにするにはどうすればよいですか?
偶然、私は Djangosnippets#1031 をContentType管理に使用しています。派生クラスを返す as_leaf_class という名前のメソッドがあります。
明らかに、派生クラスごとにフォームを作成できますが、それは非常に多くの不必要な重複です(テンプレートはすべて汎用であるため、本質的に{{form.as_p}})。
ちなみに、Animalはおそらく同じ問題を持ついくつかの無関係な基底クラスの1つであると想定するのが最善であるため、理想的な解決策は一般的です。
助けてくれてありがとう。
解決
さて、これが私がやったことであり、それはうまく機能し、賢明なデザインであるように見えます(私は修正するつもりです!)
コアライブラリ(例:mysite.core.views.create_update)で、デコレータを作成しました:
from django.contrib.contenttypes.models import ContentType
from django.views.generic import create_update
def update_object_as_child(parent_model_class):
"""
Given a base models.Model class, decorate a function to return
create_update.update_object, on the child class.
e.g.
@update_object(Animal)
def update_object(request, object_id):
pass
kwargs should have an object_id defined.
"""
def decorator(function):
def wrapper(request, **kwargs):
# may raise KeyError
id = kwargs['object_id']
parent_obj = parent_model_class.objects.get( pk=id )
# following http://www.djangosnippets.org/snippets/1031/
child_class = parent_obj.content_type.model_class()
kwargs['model'] = child_class
# rely on the generic code for testing/validation/404
return create_update.update_object(request, **kwargs)
return wrapper
return decorator
animals / views.pyには、次のものがあります:
from mysite.core.views.create_update import update_object_as_child
@update_object_as_child(Animal)
def edit_animal(request, object_id):
pass
animals / urls.pyには、次のものがあります:
urlpatterns += patterns('animals.views',
url(r'^edit/(?P<object_id>\d+)
今では、各基本クラスに固有の編集関数のみが必要です。これは、デコレータで作成するのは簡単です。
誰かがそれが役立つことを願っています。フィードバックをいただければ幸いです。
, 'edit_animal', name="edit_animal"),
)
今では、各基本クラスに固有の編集関数のみが必要です。これは、デコレータで作成するのは簡単です。
誰かがそれが役立つことを願っています。フィードバックをいただければ幸いです。
他のヒント
AFAICT、猫と犬は異なるDBテーブルにあり、おそらくAnimalテーブルはありません。ただし、すべてに1つのURLパターンを使用しています。どちらかを選択する必要があります。
猫と犬に異なるURLパターンを使用します。どちらも 'create_update.update_object'
を呼び出します。ただし、それぞれに異なる dict
を使用します。 1つは 'model':Dog
で、もう1つは 'model':Cat
または各レコードが猫または犬になる単一のテーブルが必要ですか?そのために継承モデルを使用できるとは思わない。