2009-11-30 60 views
2

我基本上构建了一个非常小的表单。让我们坚持django教程中给出的书籍/发布者示例,并以此为基础。Django ModelForm,有一个外键作为隐藏字段

我有一个用户登录到web应用程序,在这一点上他们可以做的第一件事是点击一个发布者。这位出版商随后会保存他们的会话。在那之后,我带他们去创建一本书。在那里,我将数据库中的发布者ID嵌入到隐藏字段中。

当用户提交的HTTP POST,我做这样的事情:

mybookform = BookForm(request.POST) 
if mybookform.is_valid(): 
    abook = mybookform.save(commit=False) 
    abook.publisher_id = request.POST['publisher_id'] 
    mybookform.save() 

是的,有在这里做了一些幼稚的事情,比如一味抓住PUBLISHER_ID并验证它是否确实是一个真正的发布者ID,除其他安全问题。我们暂时不关注这一点。

我的问题是,有没有更好的方法来处理?虽然假设这个例子没有物理意义,但在我的特定应用中,这个例子实际上是有道理的。问题是我得到一个ValueError异常,说publisher_id需要是一个Publisher实例。

现在我可以使用Publisher.objects.filter(id = ..)轻松地检索发布者实例并使用它。问题是,这是否真的有必要?我可以避免对数据库进行额外的查询,并以某种方式更新这个表单实例以更加“优雅”的方式吗?

另外,是否有可能以某种方式将发布者嵌入到隐藏字段中,以便我不需要执行mybookform.save(commit = False),而只需执行mybookform = BookForm(request.POST),然后执行mybookform.save ()立即?

回答

1

检索发布服务器的实例可防止可能引用完全无效的发布服务器的客户端更改。

对于第二个问题,是的,您可以通过overriding the field in the ModelForm将该字段作为隐藏字段加上适当的表单字段,将widget设置为HiddenInput

+0

感谢约翰。唯一的问题是,你的回答并不能帮助我弄清楚如何确保隐藏的输入包含publisher_id的正确实例。 – randombits 2009-11-30 01:22:31

+0

Simon Willison已经就一些签名的cookies进行了一些讨论,更一般地说,包括在Django核心中的一般签名(http://groups.google.com/group/django-developers/browse_thread/thread/133509246caf1d91)。您可以使用Simon的sign.py(http://github.com/simonw/django-openid/blob/master/django_openid/signed.py) – 2009-11-30 01:29:58

+0

nono加密签名cookie或隐藏字段的值。我并不担心加密cookies。我已经有了代码。我的问题是,外键引用了发布者,但它只能是一个发布者。我不知道如何将隐藏的发布者字段设置为用户登录到应用程序时最初放入的实例的字段。 – randombits 2009-11-30 01:32:32

0

没有更好的方法来做到这一点。

我会用get_object_or_404这个功能。

是的,你可以防止这种由用户修改设置模型场editable=False

相关问题