在Django中,给出了应用 animals 喜欢的摘录:
animals / models.py with:
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+)$', 'create_update.update_object', dict),
)
如何使用通用视图使用相同的表单编辑Dog和/或Cat?
即。传递给 animals / animal_form.html 的表单对象将是Animal,因此不会包含派生类Dog和Cat的任何细节。我怎么能让Django自动将子类的表单传递给 animal / animals_form.html ?
顺便说一句,我正在使用Djangosnippets #1031进行ContentType管理,因此Animal会有一个名为 as_leaf_class 的方法来返回派生类。
显然,可以为每个派生类创建表单,但这是非常多的不必要的重复(因为模板都是通用的 - 基本上是{{form.as_p}})。
顺便说一句,最好假设Animal可能是具有相同问题的几个不相关基类之一,因此理想的解决方案是通用的。
提前感谢您的帮助。
答案 0 :(得分: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"),
)
现在我只需要为每个基类创建一个独特的编辑函数,这对于使用装饰器创建来说是微不足道的。
希望有人觉得有帮助,我很乐意收到反馈。
答案 1 :(得分:0)
AFAICT,猫和狗在不同的数据库表上,也许没有Animal表。但你正在使用一种URL模式。你需要在每个地方之间做出选择。
我会为猫和狗使用不同的网址模式,两者都会调用'create_update.update_object'
;但每个使用不同的dict
。一个'model':Dog
,另一个'model':Cat
或者你想要一张表,每张唱片都可以是猫还是狗?我认为你不能使用继承的模型。