0

I have a Django queryset being created for a graph like the following:

obj = Allotment.objects
    .all()
    .values('dispatch_date')
    .annotate(transaction_no=Count('transaction_no'))
    .values('dispatch_date', 'transaction_no')

Now I am trying to pass all these values dynamically so I tried this :

    data = request.data.copy()
    x_model = data['x_model']
    y_model = data['y_model']
    obj = Allotment.objects
        .all()
        .values('{}'.format(x_model))
        .annotate(transaction_no=Count('{}'.format(y_model)))
        .values('{}'.format(x_model), '{}'.format(y_model))

where I just replaced the string values and it gives me the following error:

The annotation 'transaction_no' conflicts with a field on the model.

How do I dynamically change the field in annotate function? and apply aggregators such as Sum, Count, etc given that the aggregators are passed through the API as well

Rahul Sharma
  • 2,187
  • 6
  • 31
  • 76
  • 3
    Your model has a field named "transaction_no", you can't have an annotation with the same name, your first queryset should fail with the same error. Can you share the model? – Iain Shelvington Jan 07 '23 at 09:24
  • @IainShelvington Okay.. got it! But how can I pass the aggregators dynamically ? – Rahul Sharma Jan 07 '23 at 10:12

1 Answers1

0

You get the error

The annotation 'transaction_no' conflicts with a field on the model.

because you have already declared a field transaction_no in your model and you cannot use this parameter inside the annotation on the Queryset concerning this model

You can dynamically pass what you expect in annotate function using the unpacking feature of python. from your snippets, it could be something like this

annotate_dict = {
    "count_x_model":Count("x_model"),
    "count_y_model":Count("y_model")
}
second_values = ["x_model", "y_model"]

obj = Allotment.objects
        .all()
        .values('{}'.format(x_model))
        .annotate(**annotate_dict)
        .values(*second_values)

You can read about this from here What does ** (double star/asterisk) and * (star/asterisk) do for parameters?

Nwawel A Iroume
  • 1,249
  • 3
  • 21
  • 42