我有这些模型:
class UserProfile(models.Model):
name = models.CharField(max_length=100)
class Dialog(models.Model):
belong_to = models.ManyToManyField(UserProfile)
class Message(models.Model):
# Dialog to which this message belongs
part_of = models.ForeignKey(Dialog)
# User who sends message
sender = models.ForeignKey(UserProfile, related_name='sender')
# User who receives message
receiver = models.ForeignKey(UserProfile, related_name='receiver')
我想做的是限制发送者和接收者字段的选择,以便它们只能是整个对话框所属的用户。我试过这个:
sender = models.ForeignKey(UserProfile,
related_name='sender',
limit_choices_to={'dialog':1})
这限制了选择,但仅限于ID=1的对话的成员。我想知道这是否可以动态完成?
3条答案
按热度按时间kiz8lqtg1#
我不相信有任何方法可以像你想要的那样使用limit_choices_to动态过滤,因为你将无法访问所需的对象来形成这样的查询。
相反,您可能应该为message创建自己的模型表单,并在那里为这些字段设置查询集。比如下面……
此外,为什么
limit_choices_to
适用于您的示例,但不是动态有用的。Django简单地处理
limit_choices_to
表达式,作为一个额外的过滤器应用于ModelForm字段查询集。表达式{dialog: 1}
在语义上与将UserProfile.objects.filter(dialog=1)
的结果赋给我的示例中的查询集没有什么不同。Django不知道是否有一个具有该id的对话框作为关系存在于UserProfile中,它只是应用过滤器。在本例中,存在一个id为1的对话框,因此它可以正常工作。如果你在你的例子中坚持一个无效的对话框id..它将评估为一个空的查询集,你将在你的表单中得到0个选择。
它不能是动态的,因为在
limit_choices_to
中,您只能为UserProfile模型创建过滤器表达式。您不能访问字段所属的Message示例,也不能访问消息所属的Dialog模型...因此,您无法创建过滤器来动态地限制它们。创建您自己的ModelForm并限制该字段的查询集,在那里您有您需要的信息,这是正确的方法。
j0pj023g2#
在Django中没有办法动态过滤模型中的字段。为了确保没有用户输入不正确的数据,我将编辑clean方法来执行额外的验证层。(因此,管理员可能认为他们可以添加任何发送者/接收者,但如果他们提交的示例的发送者/接收者不属于对话框的用户,则会给予验证错误。这将防止用户将不正确的数据添加到您的网站之外的数据库。
然而,向您的网站添加过滤器(即视图本身)可以通过覆盖视图相关表单的初始化方法轻松完成。
如果Django在模型字段中添加动态过滤器,那么制作网站就太容易了。
snvhrwxg3#
如果
Message
的示例都属于Dialog
,为什么不在Dialog
模型上创建一个字段messages
?然后,您可以将发送方和接收方附加到每个Dialog
。简而言之,沿着这些路线的东西:消息的发送者和接收者总是对话框所属的发送者和接收者。