![](/img/trans.png)
[英]How to use the django-autocomplete-light to return the foreign-key with a valid value in the form?
[英]Django models: how to return a default value in case of a non-existing foreign-key relationship?
我正在用Django(德语 - 瑞典语)开发词汇训练计划。
应用程序的词汇数据由大量“词汇卡”组成,每个“词汇卡”包含一个或多个德语单词或与一个或多个瑞典语术语相对应的术语。
培训仅适用于注册用户,因为该应用程序通过保存每个词汇卡的score
来跟踪用户的表现。
词汇卡具有级别(基本,高级,专家)以及分配给它们的任意数量的标签。
当注册用户开始培训时,应用程序需要计算每个级别和标签的用户平均分数,以便他可以进行选择。
我通过引入名为CardByUser
的模型解决了这个问题,该模型具有score
和字段以及与模型User
和Card
ForeignKey
关系。 现在我可以使用Django的聚合函数来计算平均分数。
最大的缺点:只有当DB中当前存在的每个Card实例都有CardByUser
实例时, CardByUser
,即使用户只训练了100张卡。 我目前的解决方案是在创建Card
时以及用户注册时创建所有CardByUser
实例。 当然,就数据库存储器和计算时间而言,这都是相当无效的(注册用户需要相当长的时间)。
它似乎相当不优雅,哪种错误最让我烦恼。
有一个更好的方法吗?
也许在计算Card
的平均分数时可以告诉Django:
Card
和用户的CardByUser
,请使用其分数。 CardByUser
不存在,请使用默认值 - >得分0。 可以这样做吗? 如果是这样,怎么样?
编辑:澄清感谢S.Lott的第一个答案,但我认为我的问题有点复杂。 我的不好,我正在尝试使用我的模型中的一些实际代码来澄清。
class Card(models.Model):
entry_sv = models.CharField(max_length=200)
entry_de = models.CharField(max_length=200)
... more fields ...
class CardByUser(models.Model):
user = models.ForeignKey(User)
card = models.ForeignKey(Card, related_name="user_cards")
score = models.IntegerField(default=0)
... more fields ...
这意味着许多CardByUser
对象与单个Card
。
现在在我的视图代码中,我需要创建一个满足以下条件的CardByUser
对象的CardByUser
:
Card
对象的tag
字段包含某个字符串(我现在也不是最优的,但不是我的问题的焦点......) 然后我可以汇总得分。 我当前的代码看起来像这样(缩短):
user_cards = CardByUser.objects.filter(user=current_user)
.filter(card__tags__contains=tag.name)
avg = user_cards_agg.aggregate(Avg('score'))['score__avg']
如果当前用户和Card
的CardByUser
不存在,则它将不会包含在聚合中。 这就是我用0分创建所有CardByUser
的原因。
那我怎么能摆脱那些呢? 任何想法,将不胜感激!
这是方法(也许是属性)的用途。
class OptionalFKWithDefault( models.Model ):
another = models.ForeignKey( AnotherModel, blank=True, null=True )
@property
def another_score( self ):
if self.another is None:
return 0
else:
return self.another.score
这可能与您的问题并不完全相关,但看起来CardByUser
确实应该是与额外字段的多对多关系。 (见http://docs.djangoproject.com/en/dev/topics/db/models/#extra-fields-on-many-to-many-relationships )
也许你可以用这种方式改变模型?
class Card(models.Model):
entry_sv = models.CharField(max_length=200)
entry_de = models.CharField(max_length=200)
... more fields ...
users = models.ManyToManyField(User, through='CardByUser')
class CardByUser(models.Model):
user = models.ForeignKey(User)
card = models.ForeignKey(Card)
score = models.IntegerField(default=0)
然后你不必明确地创建CardByUser对象,因为这都是由Django处理的。 您也应该能够简化聚合查询:
user_cards = Card.objects.filter(users=current_user)
.filter(tags__contains=tag.name)
...
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.