我有以下模型,它形成了人与“Eprint”出版物之间的多对多关系。每个人的个人资料页面都会显示通过此表格引用的电子书,但仅限于show = True,以及“订单”字段的数字顺序:
class UsersEprint(models.Model):
person = models.ForeignKey(Person)
eprint = models.ForeignKey(emodels.Eprint) # this has a .title field
show = models.BooleanField(default=True)
order = models.IntegerField(default=0)
现在这一切都可以通过管理员进行管理,但我想要一个用户友好的表单进入网站上的用户个人资料页面。
理想情况下,我想要一个表格,每个人的电子邮件都有一行,给出:eprint标题(不能编辑),'show'的复选框和'order'的数字字段。 “删除”复选框也很有用。
使用modelformsets的默认方法为列出所有eprints的eprint提供了一个下拉选择器 - 这是因为表单不知道我不想编辑它。我已经尝试过覆盖字段和小部件的各种方法,但这一切看起来都有些笨拙,而且我似乎最终还是会逐行在模板中逐行渲染表单。
下一个复杂因素是,我可以使用javascript系统 - 无论是拖动行还是向上/向下移动箭头,而不是让用户键入数字来重新排序表行。当用户提交表单时,将获得新订单。
我的问题是,我在什么时候退出django的表格处理范围?我应该放弃导入django.forms并自己管理它吗?或者即使是最尴尬的形式,还有有用的位吗?
答案 0 :(得分:1)
这个问题没有“好”的答案,但我个人认为这超出了范围;)正如你自己所说,你可以控制各种庄园中呈现的田地类型,但我同意,让它感觉“kludgy”。
另外,你有没有想过你的javascript系统背后的HTML?你需要什么样的形式...如果一个视图需要一个由Django表单处理呈现的表单,它将如何处理。你可能会这样做,但我认为它真的会变得非常丑陋。
我认为你最好从头开始设计一个带有表单的模板,以及一个处理视图。不幸的是,这将花费你额外的工作来进行验证,但我认为你会赢得更多的时间使表格完全符合你的要求。
让我再说一遍,这是真的建议,我相信你可以使用标准表格处理,但如果我不得不做同样的事情我也不会。
答案 1 :(得分:1)
我认为您的用例并不特别尴尬,我确信InlineModelFormset
可以很好地处理您的所有要求。需要记住的是,Django表单的主要关注点是输入数据的验证; 演示文稿是(并且应该)取决于您。
当然,Django提供了一些表单布局的基本工具(as_ul
等),但是你不应该对它们过于依赖。自定义表单的呈现方式不应被视为“黑客”,而是一个功能; - )
因为你不会编辑
eprint,您可以排除此字段
来自底层的形式,你
传递给
inlinemodelformset_factory
;在
你的模板,只显示
而是form.instance.eprint.title
的form.eprint
(form.instance
指向底层模型
实例)
渲染表格时
formset,你可以检查
form.instance.show
- 如果是的话
True
,然后呈现表单
一般。否则,要么添加一个
形式的“隐藏”类
容器,或将字段渲染为
隐藏的输入
(form.<FIELD>.as_hidden
)。
不幸的是,你不能简单地省略
它们,因为这将导致验证
服务器上的错误
将can_delete=True
传递给
inlinemodelformset_factory
会
为每个复选框添加-DELETE
复选框
形成;你可以使用jQuery来隐藏
这个,而是渲染一个删除
按钮。单击时,按钮
设置复选框的值,然后
Django处理剩下的事情。你可以看到
这个here
订购可以使用
像jQuery UI这样的工具包 - 看看this
snippet的想法。再次,
渐进式增强是什么
你在这之后;你的所有剧本都会
do是更新order
字段,然后让
当您提交时,Django会处理实际的保存。
这样,功能仍然存在,甚至
如果Javascript被禁用(或
在客户端<缺席)
不要害怕探索和实验。并非所有的Django都有记录,但是(使用源代码,Luke :)如果您担心依赖于将来某个时候可能删除的功能,您可以随时询问Django Users