我有一个普通用户,谁拥有一些测量,每一种都可以有一个或多个标签的结果:获取相关对象
class User(AbstractBaseUser):
born = models.DateField(null=True, blank=True)
...
class Measurement(models.Model):
user = models.ForeignKey(User, related_name='measurements')
...
class MeasurementResult(models.Model):
measurement = models.ForeignKey(Measurement, related_name='results')
tag = models.CharField(max_length=255)
value = models.FloatField()
...
我想获得的所有用户,所有的测量,并与标签所有结果,这样我可以做到以下几点:
{% for user in users %}
<div class="row">
<div class="col-md-4">{{user.name}}, {{user.age}}</div>
<div class="col-md-4">{{user.tags}}</div>
<div class="col-md-4"><a href="{% url 'user_detail' user.id %}"> View detail</a></div>
</div>
{% endfor %}
我这里有一些问题,我不知道如何正确解决:
user.age
:我没有用户的年龄,但是用户出生的日期。我如何将一个从数据库中的天生属性派生的age属性添加到queryset中的用户?user.tags
:这比较棘手,因为标签是从给定用户的所有测量结果的所有标签的联合(集合)中获得的。我想我需要为此使用注释,但不知道如何去做。
目前的年龄我已经添加了一个方法,将User
型号:
class User(AbstractBaseUser):
...
def age(self):
'''Returns the age of this user'''
if not self.born:
return None
today = date.today()
return today.year - born.year - ((today.month, today.day) < (born.month, born.day))
这是添加一个属性到模型的正确,也可能?通过添加一个方法?或者是更好的Django方式这样做吗?
并添加标签,我有一个简单的辅助功能,它增加了一个属性为每个用户:
def get_users_with_tags(skip_user=None):
'''Lists all users, adding to each user the measurements results' tags'''
users = User.objects.all()
if skip_user:
users = users.exclude(pk=skip_user.id)
for user in users:
measurements = Measurement.objects.filter(user=user.id)
tags = set()
for measurement in measurements:
results = MeasurementResult.objects.filter(measurement=measurement)
for result in results:
tags.add(result.tag)
user.tags = ','.join(list(tags))
return users
但我不喜欢,我要求每个用户的测量,结果为每次测量。有没有办法在单个数据库访问中获得所有这些?我不喜欢user.tags
ad-hoc属性添加这样。有没有更好的方法来做到这一点? UserManager
也许,但如何访问Model Manager中的相关模型?
什么都可以归结为是,即使由get_users_with_tags
返回的值是通过上述Django模板非常有用的,这些相同的结果是不可用的(不可序列,因为他们是不是一个真正的QuerySet
?)对一个Django rest API。
我想改进该函数,以便产生可供django模板和django rest API框架使用的结果。
甚至不需要成为财产目录,因为Django的模板标签将识别与OP的当前模板代码 – Sayse
事实上的方法;无论如何,这里是属性装饰链接:https://docs.python.org/2/library/functions.html#property – Wtower
@Sayse,我很困惑:我需要声明它作为属性为它在任何工作背景?我的意思是,不仅在模板上下文中,而且在串行器上下文中。 – dangonfast