Advertisement
Guest User

Untitled

a guest
Dec 21st, 2021
299
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 4.75 KB | None | 0 0
  1. # MODELS
  2.  
  3. class User(AbstractUser):
  4.     employee_no = models.IntegerField(default=1)
  5.     ...all the other usual attributes...
  6.  
  7. class Summation(CreateUpdateMixin, CreateUpdateUserMixin):
  8.     # CreateUpdateMixin adds 'created_at' & 'updated_at
  9.     # CreateUpdateUserMixin adds 'created_by' & 'updated_by'
  10.     employee = models.ForeignKey(
  11.         User, on_delete=models.PROTECT, related_name="%(class)s_employee"
  12.     )
  13.     report_url = models.CharField(max_length=350, blank=True)
  14.     ...other unimportant attributes...
  15.  
  16.     def evaluations_summary(self):
  17.         evaluations_summary = (
  18.             self.evaluation_set.all()
  19.             .values("evaluation_type__name")
  20.             .annotate(Count("evaluation_type"))
  21.         )
  22.         return evaluations_summary
  23.  
  24.  
  25. class Evaluation(CreateUpdateMixin, CreateUpdateUserMixin):
  26.     summation = models.ForeignKey(Summation, on_delete=models.PROTECT)
  27.     evaluation_type = models.ForeignKey(
  28.         EvaluationType, on_delete=models.PROTECT
  29.     )
  30.     evaluation_level = models.ForeignKey(
  31.         EvaluationLevel, on_delete=models.PROTECT
  32.     )
  33.     evaluation_date = models.DateField(
  34.         auto_now=False, auto_now_add=False, null=True, blank=True
  35.     )
  36.     published = models.BooleanField(default=False)
  37.  
  38. class EvaluationLevel(CreateUpdateMixin):
  39.     name = models.CharField(max_length=50)
  40.     description = models.CharField(max_length=50)    
  41.  
  42. class EvaluationType(CreateUpdateMixin):
  43.     name = models.CharField(max_length=50)
  44.     description = models.CharField(max_length=50)
  45.     evaluation_levels = models.ManyToManyField(EvaluationLevel)  
  46.  
  47.  
  48. # SERIALIZERS
  49.  
  50. class UserSerializer(serializers.HyperlinkedModelSerializer):
  51.     multiple_locations = serializers.BooleanField()
  52.     multiple_jobs = serializers.BooleanField()
  53.     summation_status_due_date = serializers.DateField()
  54.     summation_employee = SummationSerializer(many=True, read_only=True)
  55.     evaluations_summary = serializers.SerializerMethodField()
  56.  
  57.     class Meta:
  58.         model = User
  59.         fields = [
  60.             "url",
  61.             "id",
  62.             "username",
  63.             "first_name",
  64.             "last_name",
  65.             "full_name",
  66.             "email",
  67.             "is_staff",
  68.             "multiple_locations",
  69.             "multiple_jobs",
  70.             "summation_status_due_date",
  71.             "summation_employee",
  72.             "evaluations_summary",
  73.         ]
  74.  
  75.         return (
  76.             obj.summation_employee__evaluation_set.all()
  77.             .values("evaluation_type__name")
  78.             .annotate(Count("evaluation_type"))
  79.         )
  80.  
  81.  
  82. # CURRENT ANNOTATIONS
  83.  
  84.     # Subquerries for evaluation_summary
  85.     active_summations = (
  86.         Summation.objects.filter(employee=OuterRef("pk"), locked=False)
  87.     )
  88.     evaluations_set = (
  89.         Evaluation.objects.filter(summation__in=active_summations)
  90.         .order_by()
  91.         .values("evaluation_type__name")
  92.     )
  93.     summary_set = evaluations_set.annotate(Count("evaluation_type"))
  94.  
  95.     user_list = (
  96.         User.objects.prefetch_related("summation_employee")
  97.         .prefetch_related("summation_employee__evaluation_set")
  98.         .filter(id__in=all_user_ids)
  99.         # Get the total locations and if > 1, set multiple_locations to True
  100.         .annotate(total_locations=Subquery(total_locations))
  101.         .annotate(
  102.             multiple_locations=Case(
  103.                 When(total_locations__gt=1, then=Value(True)),
  104.                 default=Value(False),
  105.                 output_field=BooleanField(),
  106.             )
  107.         )
  108.         # Get the total jobs and if > 1 set mutiple_jobs to True
  109.         .annotate(total_jobs=Subquery(total_jobs))
  110.         .annotate(
  111.             multiple_jobs=Case(
  112.                 When(total_jobs__gt=1, then=Value(True)),
  113.                 default=Value(False),
  114.                 output_field=BooleanField(),
  115.             )
  116.         )
  117.         # Get the due_date of the summation from the SummationStatus object
  118.         .annotate(
  119.             summation_status_due_date=Subquery(
  120.                 summation_status.values("summation_due")
  121.             )
  122.         )
  123.         # I need to add the annotation here for the 'evaluations_summary' to avoid
  124.         # having the database hit for every user (which could possibly range into the
  125.         # thousands in certain cases)
  126.         # I have tried a number of ways to obtain what I'm looking for
  127.         .annotate(
  128.             evaluations_summary=Subquery(
  129.                 evaluations_set.order_by()
  130.                 .values("evaluation_type__name")
  131.                 .annotate(Count("evaluation_type"))
  132.             )
  133.         )
  134.         # this annotation gives the error: Only one expression can be specified in the
  135.         # select list when the subquery is not introduced with EXISTS.
  136.  
  137.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement