Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- # MODELS
- class User(AbstractUser):
- employee_no = models.IntegerField(default=1)
- ...all the other usual attributes...
- class Summation(CreateUpdateMixin, CreateUpdateUserMixin):
- # CreateUpdateMixin adds 'created_at' & 'updated_at
- # CreateUpdateUserMixin adds 'created_by' & 'updated_by'
- employee = models.ForeignKey(
- User, on_delete=models.PROTECT, related_name="%(class)s_employee"
- )
- report_url = models.CharField(max_length=350, blank=True)
- ...other unimportant attributes...
- def evaluations_summary(self):
- evaluations_summary = (
- self.evaluation_set.all()
- .values("evaluation_type__name")
- .annotate(Count("evaluation_type"))
- )
- return evaluations_summary
- class Evaluation(CreateUpdateMixin, CreateUpdateUserMixin):
- summation = models.ForeignKey(Summation, on_delete=models.PROTECT)
- evaluation_type = models.ForeignKey(
- EvaluationType, on_delete=models.PROTECT
- )
- evaluation_level = models.ForeignKey(
- EvaluationLevel, on_delete=models.PROTECT
- )
- evaluation_date = models.DateField(
- auto_now=False, auto_now_add=False, null=True, blank=True
- )
- published = models.BooleanField(default=False)
- class EvaluationLevel(CreateUpdateMixin):
- name = models.CharField(max_length=50)
- description = models.CharField(max_length=50)
- class EvaluationType(CreateUpdateMixin):
- name = models.CharField(max_length=50)
- description = models.CharField(max_length=50)
- evaluation_levels = models.ManyToManyField(EvaluationLevel)
- # SERIALIZERS
- class UserSerializer(serializers.HyperlinkedModelSerializer):
- multiple_locations = serializers.BooleanField()
- multiple_jobs = serializers.BooleanField()
- summation_status_due_date = serializers.DateField()
- summation_employee = SummationSerializer(many=True, read_only=True)
- evaluations_summary = serializers.SerializerMethodField()
- class Meta:
- model = User
- fields = [
- "url",
- "id",
- "username",
- "first_name",
- "last_name",
- "full_name",
- "email",
- "is_staff",
- "multiple_locations",
- "multiple_jobs",
- "summation_status_due_date",
- "summation_employee",
- "evaluations_summary",
- ]
- return (
- obj.summation_employee__evaluation_set.all()
- .values("evaluation_type__name")
- .annotate(Count("evaluation_type"))
- )
- # CURRENT ANNOTATIONS
- # Subquerries for evaluation_summary
- active_summations = (
- Summation.objects.filter(employee=OuterRef("pk"), locked=False)
- )
- evaluations_set = (
- Evaluation.objects.filter(summation__in=active_summations)
- .order_by()
- .values("evaluation_type__name")
- )
- summary_set = evaluations_set.annotate(Count("evaluation_type"))
- user_list = (
- User.objects.prefetch_related("summation_employee")
- .prefetch_related("summation_employee__evaluation_set")
- .filter(id__in=all_user_ids)
- # Get the total locations and if > 1, set multiple_locations to True
- .annotate(total_locations=Subquery(total_locations))
- .annotate(
- multiple_locations=Case(
- When(total_locations__gt=1, then=Value(True)),
- default=Value(False),
- output_field=BooleanField(),
- )
- )
- # Get the total jobs and if > 1 set mutiple_jobs to True
- .annotate(total_jobs=Subquery(total_jobs))
- .annotate(
- multiple_jobs=Case(
- When(total_jobs__gt=1, then=Value(True)),
- default=Value(False),
- output_field=BooleanField(),
- )
- )
- # Get the due_date of the summation from the SummationStatus object
- .annotate(
- summation_status_due_date=Subquery(
- summation_status.values("summation_due")
- )
- )
- # I need to add the annotation here for the 'evaluations_summary' to avoid
- # having the database hit for every user (which could possibly range into the
- # thousands in certain cases)
- # I have tried a number of ways to obtain what I'm looking for
- .annotate(
- evaluations_summary=Subquery(
- evaluations_set.order_by()
- .values("evaluation_type__name")
- .annotate(Count("evaluation_type"))
- )
- )
- # this annotation gives the error: Only one expression can be specified in the
- # select list when the subquery is not introduced with EXISTS.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement