tl;dr : モデルのフォームを特定のモデルに関連付ける簡単な方法を探しています。モデルだけを知っていれば、適切な作成/編集フォームをレンダリングできます。対応する の名前を Model クラスの文字列属性として保存することで解決策を開発しましたが、ModelForm
django を初めて使用するので、これが望ましい解決策であるかどうか興味があります。
私は、多数の製品グループのタスクを保存する django タスク/プロジェクト管理サイトに取り組んでいます。mysite/<ProductGroup>/create_task.html
に移動すると、その製品グループ内でタスク/プロジェクトを作成するためのフォームにユーザーを誘導する必要があります。デフォルトではTask
、単純な を使用して基本モデル インスタンスを編集できますModelForm
。Task
ただし、特定の製品グループについては、モデルをサブクラス化し (例) 、そのサブクラスに固有のものをSalesTask
表示するオプションが必要です (例)。 ModeForm
SalesTaskForm
私の現在の解決策は、 task-object-type を contenttype としてProductGroup
モデルに保存することです。
class ProductGroup(models.Model):
task_type = models.ForeignKey(ContentType)
...
<define other fields here>
ModelForm
次に、レンダリング時に対応するものを使用する特別な文字列属性を持つベース タスク モデルを定義します。
<models.py>
class Task(models.Model):
product_group = models.ForeignKey(ProductGroup)
...
<define task fields common to all Task subclasses>
...
# Associate model with a form (regular python class attribute,
# not a django field)
form = 'TaskForm'
<forms.py>
class TaskForm(ModelForm):
class Meta:
model = Task
*Note that it would be slightly more convenient if I could set Task.form equal
to the actual TaskForm(ModelForm) class rather than a string, but I couldn't
get around the circular imports when trying this route (models.py `Task`
would need to import `Taskorm` from forms.py, which itself needs to import
`Task`).*
この設定により、特定の製品グループの Task モデルを簡単に拡張できます。これは、 と をサブクラスTask
化し、モデル サブクラス定義TaskForm
の属性 (例: ) をオーバーライドしてから、 の sales インスタンスに task_type 外部キーを設定するだけです。Task.form
SalesTask.form = 'SalesTaskForm'
ProductGroup
結果のcreate_task
ビュー関数は、特定の製品グループに適したフォームをインテリジェントにレンダリングできます。
<views.py>
...
import mysite.forms as taskforms
...
def create_task(request, name):
try:
product_group = ProductGroup.object.get(product_group_iexact=name)
except ProductGroup.DoesNotExist:
raise Http404
if request.method == 'POST':
task_model = product_group.item_type.model_class()
try:
form = taskforms.__getattribute__(task_model.form)
except AttributeError:
raise Http404
if form.is_valid():
# Process form
...
これは機能しているようで、解決策に不満はありませんが、フォームを特定のモデルに関連付ける必要があるのは一般的なようで、django には比較的新しいので、組み込みまたはこれに対処するより雄弁な方法は?
前もって感謝します。