Пример #1
0
 def add_processing(self, process_id):
     if self.id:
         self.__class__.objects.filter(id=self.id).update(
             _background_process_ids=CombinedExpression(
                 F('_background_process_ids'),
                 '||',
                 Value([process_id], ArrayField(models.CharField(max_length=255)))
             )
         )
     self._background_process_ids.append(process_id)
Пример #2
0
def test_upsert_with_update_condition():
    """Tests that an expression can be used as an upsert update condition."""

    model = get_fake_model({
        "name": models.TextField(unique=True),
        "priority": models.IntegerField(),
        "active": models.BooleanField(),
    })

    obj1 = model.objects.create(name="joe", priority=1, active=False)

    # should not return anything because no rows were affected
    assert not model.objects.upsert(
        conflict_target=["name"],
        update_condition=CombinedExpression(
            model._meta.get_field("active").get_col(model._meta.db_table),
            "=",
            ExcludedCol("active"),
        ),
        fields=dict(name="joe", priority=2, active=True),
    )

    obj1.refresh_from_db()
    assert obj1.priority == 1
    assert not obj1.active

    # should return something because one row was affected
    obj1_pk = model.objects.upsert(
        conflict_target=["name"],
        update_condition=CombinedExpression(
            model._meta.get_field("active").get_col(model._meta.db_table),
            "=",
            Value(False),
        ),
        fields=dict(name="joe", priority=2, active=True),
    )

    obj1.refresh_from_db()
    assert obj1.pk == obj1_pk
    assert obj1.priority == 2
    assert obj1.active
Пример #3
0
def ac_rate(request):
    rate = CombinedExpression(ac_count / Count('submission'), '*', Value(100.0), output_field=FloatField())
    data = Language.objects.annotate(total=Count('submission'), ac_rate=rate).filter(total__gt=0) \
        .values('key', 'name', 'short_name', 'ac_rate').order_by('total')
    return JsonResponse({
        'labels': map(itemgetter('name'), data),
        'datasets': [
            {
                'fillColor': 'rgba(151,187,205,0.5)',
                'strokeColor': 'rgba(151,187,205,0.8)',
                'highlightFill': 'rgba(151,187,205,0.75)',
                'highlightStroke': 'rgba(151,187,205,1)',
                'data': map(itemgetter('ac_rate'), data),
            }
        ]
    })
Пример #4
0
def ac_rate(request):
    rate = CombinedExpression(ac_count / Count('submission'), '*', Value(100.0), output_field=FloatField())
    data = Language.objects.annotate(total=Count('submission'), ac_rate=rate).filter(total__gt=0) \
        .values('key', 'name', 'ac_rate').order_by('total')
    return JsonResponse({
        'labels': list(map(itemgetter('name'), data)),
        'datasets': [
            {
                'backgroundColor': 'rgba(151,187,205,0.5)',
                'borderColor': 'rgba(151,187,205,0.8)',
                'borderWidth': 1,
                'hoverBackgroundColor': 'rgba(151,187,205,0.75)',
                'hoverBorderColor': 'rgba(151,187,205,1)',
                'data': list(map(itemgetter('ac_rate'), data)),
            },
        ],
    })
Пример #5
0
    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)

        if not (self.object.ended or self.can_edit):
            raise Http404()

        queryset = Submission.objects.filter(contest_object=self.object)

        ac_count = Count(
            Case(When(result='AC', then=Value(1)),
                 output_field=IntegerField()))
        ac_rate = CombinedExpression(ac_count / Count('problem'),
                                     '*',
                                     Value(100.0),
                                     output_field=FloatField())

        status_count_queryset = list(
            queryset.values('problem__code', 'result').annotate(
                count=Count('result')).values_list('problem__code', 'result',
                                                   'count'), )
        labels, codes = [], []
        contest_problems = self.object.contest_problems.order_by(
            'order').values_list('problem__name', 'problem__code')
        if contest_problems:
            labels, codes = zip(*contest_problems)
        num_problems = len(labels)
        status_counts = [[] for i in range(num_problems)]
        for problem_code, result, count in status_count_queryset:
            if problem_code in codes:
                status_counts[codes.index(problem_code)].append(
                    (result, count))

        result_data = defaultdict(partial(list, [0] * num_problems))
        for i in range(num_problems):
            for category in _get_result_data(defaultdict(
                    int, status_counts[i]))['categories']:
                result_data[category['code']][i] = category['count']

        stats = {
            'problem_status_count': {
                'labels':
                labels,
                'datasets': [{
                    'label':
                    name,
                    'backgroundColor':
                    settings.DMOJ_STATS_SUBMISSION_RESULT_COLORS[name],
                    'data':
                    data,
                } for name, data in result_data.items()],
            },
            'problem_ac_rate':
            get_bar_chart(
                queryset.values(
                    'contest__problem__order',
                    'problem__name').annotate(ac_rate=ac_rate).order_by(
                        'contest__problem__order').values_list(
                            'problem__name', 'ac_rate'), ),
            'language_count':
            get_pie_chart(
                queryset.values('language__name').annotate(
                    count=Count('language__name')).filter(
                        count__gt=0).order_by('-count').values_list(
                            'language__name', 'count'), ),
            'language_ac_rate':
            get_bar_chart(
                queryset.values('language__name').annotate(
                    ac_rate=ac_rate).filter(ac_rate__gt=0).values_list(
                        'language__name', 'ac_rate'), ),
        }

        context['stats'] = mark_safe(json.dumps(stats))

        return context
Пример #6
0
    def get_ordering_value(self, qs: QuerySet,
                           value: Any) -> Tuple[QuerySet, OrderingFieldType]:

        return qs, CombinedExpression(F(self.field_name), "->", Value(value))
Пример #7
0
    def move_subtree(self, node, new_parent):
        """
        Moves a node and all its descendants under the given new parent.
        If the parent is None, the node will become a root node.

        If the `node` is equal to the new parent, or is an ancestor of it,
        raises BadMove.

        If node's parent is already new_parent, returns immediately.

        NOTE:
        This updates all the nodes in the database, and the current node instance.
        It cannot update any other node instances that are in memory, so if you have some
        whose ltree paths are affected by this function you may need to refresh them
        from the database.
        """
        if node.is_ancestor_of(new_parent, include_self=True):
            raise BadMove(
                "%r can't be made a child of %r" %
                (node.ltree, new_parent.ltree if new_parent else None))

        # Check if there's actually anything to do, return if not
        if node.parent_id is None:
            if new_parent is None:
                return
        elif new_parent is not None and node.ltree.parent(
        ) == new_parent.ltree:
            return

        old_parent_ltree = node.ltree.parent()
        old_parent_level = old_parent_ltree.level() if old_parent_ltree else -1

        # An expression which refers to the part of a given node's path which is
        # not in the current node's old parent path.
        # i.e. when node is 'a.b.c', the old parent will be 'a.b',
        # so for a descendant called 'a.b.c.d.e' we want to find 'c.d.e'.
        ltree_tail_expr = Subpath(models.F('ltree'), old_parent_level + 1)

        # Update the ltree on all descendant nodes to match new_parent
        qs = self.filter(ltree__descendant_or_equal=node.ltree)
        if new_parent is None:
            new_ltree_expr = ltree_tail_expr
        else:
            # TODO: how to do this without raw sql? django needs a cast expression
            # here otherwise the concat() fails because the ltree is interpreted
            # as text. Additionally, there's no available concatenation operator for ltrees
            # exposable in django.
            new_ltree_expr = CombinedExpression(lhs=RawSQL(
                '%s::ltree', [new_parent.ltree]),
                                                connector='||',
                                                rhs=ltree_tail_expr)
        qs.update(
            ltree=new_ltree_expr,
            # Update parent at the same time as ltree, otherwise the check constraint fails
            parent=models.Case(models.When(
                pk=node.pk,
                then=models.Value(new_parent.ltree if new_parent else None)),
                               default=Subpath(new_ltree_expr, 0, -1),
                               output_field=node.__class__._meta.get_field(
                                   'parent')))

        # Update node in memory
        node.parent = new_parent
        node._set_ltree()
        node.save(update_fields=['parent'])