我无法创建视图集,无法对相关模型中的字段进行计算。我是Django的新手,所以请放轻松。 :)
本质上。我有一个角色模型。还有一个Raids模型。 Raids模型与Character具有ManyToMany关系。每次突袭都是值得的。我认为我对这些值进行了总结。
我的主要问题是,我希望能够为每个角色计算30、60、90天和一生的出勤率。而且我很努力。您可以提供任何帮助,我将不胜感激。
编辑:我正在寻找每个字符的raid.value之和(我已经这样做了,但是我不确定是否有更好/更干净的方法)。另外,困难的部分是试图提高出勤率。所以本质上。我想划分一个角色参加的突袭次数/突袭总数(在4个不同的时间范围内)
models.py
from datetime import timedelta
from django.contrib.auth.models import User
from django.db import models
from django.utils import timezone
...
class Character(models.Model):
name = models.CharField(
'Name',
unique=True,
primary_key=True,
max_length=25,
)
...
class Raid(CreatedModifiedAbstractModel):
value = models.PositiveSmallIntegerField('DKP Value')
datetime = models.DateTimeField('Date',auto_created=True)
characters = models.ManyToManyField(
Character,
verbose_name='Attendees',
related_name='raids',
)
not_attendance = models.BooleanField('Not for Attendance',default=False)
views.py
class Dkp(viewsets.ModelViewSet):
serializer_class = DkpSerializer
permission_classes = [permissions.IsAuthenticatedOrReadOnly]
def get_queryset(self, *args, **kwargs):
date_30 = timezone.now() - timedelta(days=30)
date_60 = timezone.now() - timedelta(days=60)
date_90 = timezone.now() - timedelta(days=90)
all_raids = Raid.objects.filter(not_attendance=False)
qs = Character.objects.all()
qs = qs.extra(
select=all_raids.aggregate(
raid_30=Count('id', filter=Q(datetime__gte=date_30)),
raid_60=Count('id', filter=Q(datetime__gte=date_60)),
raid_90=Count('id', filter=Q(datetime__gte=date_90)),
raid_life=Count('id'),
)
)
qs = qs.annotate(
earned_dkp=Coalesce(Sum('raids__value'), 0),
spent_dkp=Coalesce(Sum('purchases__value'), 0),
current_dkp=F('earned_dkp') - F('spent_dkp'),
att_30=Count('raids', filter=(Q(raids__not_attendance=False) & Q(raids__datetime__gte=date_30)), default=0),
att_60=Count('raids', filter=(Q(raids__not_attendance=False) & Q(raids__datetime__gte=date_60)), default=0),
att_90=Count('raids', filter=(Q(raids__not_attendance=False) & Q(raids__datetime__gte=date_90)), default=0),
att_life=Count('raids', filter=Q(raids__not_attendance=False), default=0),
)
return qs
serializers.py
class DkpSerializer(CharacterSerializer):
current_dkp = serializers.IntegerField(read_only=True)
earned_dkp = serializers.IntegerField(read_only=True)
spent_dkp = serializers.IntegerField(read_only=True)
att_30 = serializers.IntegerField(read_only=True)
att_60 = serializers.IntegerField(read_only=True)
att_90 = serializers.IntegerField(read_only=True)
att_life = serializers.IntegerField(read_only=True)
raid_30 = serializers.IntegerField(read_only=True)
raid_60 = serializers.IntegerField(read_only=True)
raid_90 = serializers.IntegerField(read_only=True)
raid_life = serializers.IntegerField(read_only=True)
rate_30 = serializers.IntegerField(read_only=True)
raids = RaidSerializer(read_only=True, many=True)
purchases = ItemPurchaseSerializer(read_only=True, many=True)
答案 0 :(得分:1)
我的主要问题是,我希望能够为每个角色计算30、60、90天和一生的出勤率。
import datetime
from django.db.models import Count, Q
date_30 = datetime.datetime.now() + datetime.timedelta(-30)
date_60 = datetime.datetime.now() + datetime.timedelta(-60)
date_90 = datetime.datetime.now() + datetime.timedelta(-90)
Character.objects.annotate(
raid_30 = Count('raids', filter=Q(raids__datetime__gte=date_30)),
raid_60 = Count('raids', filter=Q(raids__datetime__gte=date_60)),
raid_90 = Count('raids', filter=Q(raids__datetime__gte=date_90)),
raid_life = Count('raids')
)
我正在寻找每个字符的raid.value的总和(我已经做到了,但是我不确定是否有更好/更干净的方法)。
from django.db.models import Sum
Character.objects.annotate(
raid_value = Sum('raids__value')
)
我想划分一个角色参加的突袭次数/突袭总数(在4个不同的时间范围内)
raids_count = Raid.objects.aggregate(
raid_30 = Count('pk', filter=Q(datetime__gte=date_30)),
raid_60 = Count('pk', filter=Q(datetime__gte=date_60)),
raid_90 = Count('pk', filter=Q(datetime__gte=date_90)),
raid_life = Count('pk'),
)
Character.objects.annotate(
raid_30 = Count('raids', filter=Q(raids__datetime__gte=date_30)),
raid_60 = Count('raids', filter=Q(raids__datetime__gte=date_60)),
raid_90 = Count('raids', filter=Q(raids__datetime__gte=date_90)),
raid_life = Count('raids')
).annotate(
raid_30_percent = F('raid_30')/raids_count['raid_30'],
raid_60_percent = F('raid_60')/raids_count['raid_60'],
raid_90_percent = F('raid_90')/raids_count['raid_90'],
raid_life_percent = F('raid_life')/raids_count['raid_life'],
)