假设我有这个模型(不是真正的代码):
class Message(models.Model):
content = models.CharField(...)
mentions = models.ManyToManyField(User)
内容可以是:
打电话给@Adam和@Bernard
在消息模型中保存()," Adam"和伯纳德"从文本中提取,并将其各自的用户实例添加到提及中,以便
>>> m = Message.objects.create(content="Say hi to @Adam and @Bernard")
>>> m.mentions.all()
>>> [User: Adam, User: Bernard]
现在,关于我的问题:
我如何应对伯纳德表演性变化并将自己重新命名为伯纳达?我非常希望内容能够阅读Say hi to @Adam and @Bernarda
。
基本上,我在保存时尝试了用ID替换姓名的策略(Say hi to @Adam and @Bernard
然后变为Say hi to @1 and @2
,即他们的User.pk' s。这在保存时工作正常,在阅读时可以正常工作。
在模型的save()方法中进行此替换可以正常工作,但读取和查找操作是一个主要问题。我找不到一种简单的方法来确保存储在数据库中的内容(即Say hi to @1 and @2
)'神奇地'无论何时被查询(通过.filter()和相关操作)或其实例被评估,它都会变为Say hi to @Adam and @Bernard
。
我不确定我是否走在正确的轨道上;任何以不同方式做这些事情的指针或想法都是非常受欢迎的!
答案 0 :(得分:3)
编写自定义模型字段类,扩展了CharField,您应该重读the documentation first,以便了解其中的内容,
元类 = models.SubfieldBase是自定义字段调用自定义to_python方法所必需的
覆盖to_python(),it takes a database value并返回一个python值,在那里你可以用用户#1的用户名替换@ 1(比如@Adam或@Bernarda ),
覆盖get_prep_value(),it takes a python value并且应该返回SQL的值,在那里你可以用用户管理员的pk替换@Adam(比如@ 1),
查询提及,例如Message.objects.filter(mention=someuser)
,或创建另一个字段:一个包含已更换的版本,另一个包含可能已过期的用户名 - 我不知道推荐后者
您还可以查询内容,例如Message.objects.filter(content__contains='@1')
Voodoo一般不会有任何好处,我会制作一个替换的模型方法get_content_display()
,以及一个显示内容的html版本的模板标签 - 因为你的可能想要将@Adam链接到他的用户页面。我会坚持这个,因为那是KISS。
CREDITS到LaundroMat 调试此答案并修复它(有2个错误和1个不准确,他调试并回来报告!!!)。除非你有更好的方式来奖励他,否则还要强烈反对他的评论。 Rock'on。