Throwing ZeroDivisionError - python

I need to get a calculation of some data so, in annotate I put some maths logic with other field but whenever there is 0 it is throwing an error. I need to handle that error in annotate. My code looks like this:
total_amount = Invoice.objects.filter(client_account__account_UID=account_UID,
created_at__range=(from_date, to_date)
).aggregate(Sum('total_amount'))['total_amount__sum']
total_billable_leads = CampaignContact.objects.filter(campaign=campaigns, billable=True, billable_item__created_at__range=(from_date, to_date)).count()
cch = CampaignContactHistory.objects.annotate(
campaign_name=F('campaign__name')
).values('campaign_name'
).filter(id__in=cch_ids
).annotate(
total=Count('lead_status'),
scheduled=Count(Case(When(lead_status='10', then=1))),
total_billable=(int(total_amount) / total_billable_leads) * Count(Case(When(campaign_contact__billable=True, then=1))),
)
In total_billable, there is total_billable_leads variable which may have Zero(0) then on a division it will throw an error. So, please help me to handle this exception in annotate.
CampaignContactHistory Model
class CampaignContactHistory(DateAwareModel):
campaign_contact = models.ForeignKey(CampaignContact, on_delete=models.CASCADE)
lead_status = models.CharField(max_length=20, choices=leadstatus, default=FRESH)
campaigner = models.ForeignKey(Resource, on_delete=models.CASCADE)
response_date = models.DateTimeField(null=True, blank=True)
first_reponse = models.TextField(blank=True, null=True, default='')
second_reponse = models.TextField(blank=True, null=True, default='')
campaign = models.ForeignKey(Campaign, null=True, blank=True)
For result I want if it is an error or zero(0) it should return zero(0) otherwise the calculated value.

the total_amount and total_billable_leads are constants so you get the error on python level, so the solution is:
if total_billable_leads:
total_amount_avg = int(total_amount) / total_billable_leads
else:
total_amount_avg = 0
cch = CampaignContactHistory.objects.annotate(
campaign_name=F('campaign__name')
).values('campaign_name'
).filter(id__in=cch_ids
).annotate(
total=Count('lead_status'),
scheduled=Count(Case(When(lead_status='10', then=1))),
total_billable=total_amount_avg * Count(Case(When(campaign_contact__billable=True, then=1))),
# ^^^^^^^^^^^^^^^
)

Related

Add quantity for every the same Client and Product in Django

I have 3 models, CustomerPurchaseOrderDetail, Customer and Product model, if Customer1 buy a product for example, Meat. it will save in CustomerPurchaseOrderDetail and if that Customer1 add another Meat Product, instead of adding another record to the database it will simply just add quantity.
this is my views.py
def batchaddtocart(request):
userID = request.POST.get("userID")
client = Customer(id=userID)
vegetables_id = request.POST.get("id")
v = Product(id=vegetables_id)
price = request.POST.get("price")
discount = request.POST.get("discount_price")
insert, create = CustomerPurchaseOrderDetail.objects.get_or_create(
profile=client,
products=v,
unitprice=price,
quantity=1,
discounted_amount=discount,
discounted_unitprice=discount,
)
order_qs = CustomerPurchaseOrderDetail.objects.filter\
(
profile=client,
products=v,
unitprice=price,
quantity=1,
discounted_amount=discount,
discounted_unitprice=discount
)
for order in order_qs:
if order.profile == client and order.products == v:
insert.quantity += 1
print(insert.quantity)
insert.save()
insert.save()
this is my models.py
class CustomerPurchaseOrderDetail(models.Model):
profile = models.ForeignKey(Customer,
on_delete=models.SET_NULL, null=True, blank=True,
verbose_name="Client Account")
products = models.ForeignKey(Product,
on_delete=models.SET_NULL, null=True, blank=True,
verbose_name="Product")
quantity = models.IntegerField(max_length=500, null=True, blank=True, default=1)
class Product(models.Model):
product = models.CharField(max_length=500)
class Customer(models.Model):
user = models.OneToOneField(User, related_name="profile", on_delete=models.CASCADE)
firstname = models.CharField(max_length=500, blank=True)
lastname = models.CharField(max_length=500, blank=True)
contactNumber = models.CharField(max_length=500, blank=True)
email = models.CharField(max_length=500, blank=True)
I did not encounter an error but the functionality I wanted did not work. it does not add additional quantity even if the same product is added to the list purchased by Customer1.
the problem is in following lines client = Customer(id=userID) and v = Product(id=vegetables_id) every time your function is called you are creating new customer and product objects instead of using existing objects is your database. replace them with client,created = Customer.objects.get_or_create(id=userID) and same for product v,v_created = Product.objects.get_or_create(id=vegetables_id)
When you use get_or_create method, it will create a new entry whenever at least one parameter is different enough to did not match any registered value. So, if you pass the quantity parameter equals 1, it always will create a new entry when quantity is 2+, for instance.
You should filter first with only the "fixed" parameters and create a new entry if you get nothing. Otherwise, just increment quantity.
Something like this:
order = None
order_qs = CustomerPurchaseOrderDetail.objects.filter\
(
profile=client,
products=v,
unitprice=price,
discounted_amount=discount,
discounted_unitprice=discount
)
if not order_qs:
order = CustomerPurchaseOrderDetail.objects.create(
profile=client,
products=v,
unitprice=price,
quantity=1,
discounted_amount=discount,
discounted_unitprice=discount,
)
else:
for order in order_qs:
if order.profile == client and order.products == v:
# NOTE: Please, note if you need to check your other parameters too (unityprice, discounted....)
order.quantity += 1
print(order.quantity)
order.save()

How to loop through object fields in django

I want to loop through the object fields to update their values but im not quite sure how to do this.
class FinancePending(models.Model):
invoiceNumber = models.IntegerField
amountPaid = models.CharField(max_length=20)
AmountPending = models.IntegerField( blank=True, null=True)
TotalAmount = models.CharField(max_length=50, default=0)
Now i want to calculate amountpending in a function. But its not working
amount_paid = FinancePending.objects.values_list('amountPaid', flat=True)
amount_paid = list(amount_paid)
total_amount = FinancePending.objects.values_list('TotalAmount', flat=True)
total_amount = list(total_amount)
# total - paid
TotalFee = [float(s.replace(',', '')) for s in total_amount]
AmountPaid = [float(s.replace(',', '')) for s in amount_paid]
finance_pending = FinancePending.objects.all()
i = 0
while i < len(TotalFee):
amount_pending = TotalFee[i] - AmountPaid[i]
FinancePending.objects.filter(invoiceNumber=i).values(AmountPending=amount_pending)
setattr(finance_pending, 'AmountPending', str(amount_pending))
i = 1 + i
Would suggest using Query Expression, more powerful and robust

How to add additional model to list and filter on custom condition

I have 4 models from 4 different tables :
class Profile(models.Model):
player_name = models.CharField(max_length=150)
player_surname=models.CharField(max_length=200)
sport_type=models.CharField(max_length=200)
class Results_2019(models.Model):
player_name = models.CharField(max_length=150)
first_score=models.DecimalField(decimal_places=2)
second_score=models.DecimalField(decimal_places=2)
average_score=models.DecimalField(decimal_places=2)
class Results_2018(models.Model):
player_name = models.CharField(max_length=150)
first_score=models.DecimalField(decimal_places=2)
second_score=models.DecimalField(decimal_places=2)
average_score=models.DecimalField(decimal_places=2)
class Weight(models.Model):
player_name = models.CharField(max_length=150)
year2019=models.DecimalField(decimal_places=2)
year2018=models.DecimalField(decimal_places=2)
I use these models to filter based on meeting certain condition. Foreign key does not work for me ( i tried i do not what is wrong).
ABC = []
for MyResults in [Results_2019, Results_2018 ]:
results_list = MyResults.objects.annotate(increase=F('second_score') /
F('first_score'),total=F('second_score') +
F('first_score',).filter(increase__gt=0.2,total__gt=average_score,)
ABC.extend(results_list.values_list('player_name', flat=True))
DoubleSNames = list(set([x for x in ABC if ABC.count(x) == 2]))
finallist=list(Profile.objects.filter(player_name__in=DoubleSNames).
values_list('player_name', 'player_surname'))
This code returns list of players and their surname who meet the criteria.
However i can't embed Weight class in list and filter based on
score_weight=first_score/Weight.year19
and then filter if score_weight > 30
I tried to embed
weight_list=[Weight.year19,Weight.year18]
How can i use weight_list with MyResults to calculate score_weight=first_score/Weight.year19
How to to do it?
Is that possible at all to do that ?
Additional:
When i asked you this question i minimised formula i put in filter so after i understand code answered i learn and i can solve independently. Which i did the majority, however i get lost as i haven't done that before but want to learn.
However there are 2 formula I can't insert in the code and make it work. I am keep learning and some are confusing.
Questions:
So the code answered to the question in annotate:
total=F('second_score') + F('first_score')
This is from the code.
Formula I want to embed and filter is:
total_growth=total2019/total2018
So total of 2019 divided by total of 2018). In Python there is the list I tried to apply like:
total_growth=list(map(lambda i,w: (i/w) if w else 0, total[0],total[1]))
And check on condition whether total_growth > 0.05
However it does not work and i do not exactly where to put it in the code to make it work?
How to filter by sport_type (class Profile) so sport_type is not in football.
Would appreciate help to my additional queries to close finally my concern over this question.
I wrote my own code, you are right the result is always empty because of this conditions:
total=second+first
score_weight=total/weight19
if increase > 0.2 and total > average and average > 50 and total > 70 and
score_weight > 30 : ABC.append(result.player_name)
score_weight will never be > 30
you can find below my code, when I put score_weight > 1 I can get results:
model.py:
class Profile(models.Model):
player_name = models.CharField(max_length=150)
player_surname = models.CharField(max_length=200)
sport_type = models.CharField(max_length=200)
class Results2019(models.Model):
player_name = models.CharField(max_length=150)
first_score = models.DecimalField(decimal_places=2, max_digits=5, null=True, blank=True,)
second_score = models.DecimalField(decimal_places=2, max_digits=5, null=True, blank=True,)
average_score = models.DecimalField(decimal_places=2, max_digits=5, null=True, blank=True,)
class Results2018(models.Model):
player_name = models.CharField(max_length=150)
first_score = models.DecimalField(decimal_places=2, max_digits=5, null=True, blank=True,)
second_score = models.DecimalField(decimal_places=2, max_digits=5, null=True, blank=True,)
average_score = models.DecimalField(decimal_places=2, max_digits=5, null=True, blank=True,)
class Weight(models.Model):
player_name = models.CharField(max_length=150)
year19 = models.DecimalField(decimal_places=2, max_digits=5, null=True, blank=True,)
year18 = models.DecimalField(decimal_places=2, max_digits=5, null=True, blank=True,)
views.py
def myPageView():
ABC = {}
players = Profile.objects.all().values()
for result in players:
for data in [[Results2019, 'year19'], [Results2018, 'year18']]:
Results = data[0].objects.get(player_name__exact=result['player_name'])
if Results:
wgt = Weight.objects.filter(player_name__exact=result['player_name']).values(data[1]).last()
if wgt:
if float(Results.first_score) > 0.0:
increase19 = float(Results.second_score) / float(Results.first_score)
else:
increase19 = 0
total = float(Results.second_score) + float(Results.first_score)
score_weight = total / float(wgt[data[1]])
if (increase19 > 0.2) and (total > float(Results.average_score)) and \
(float(Results.average_score) > 50) and (total > 70) and (score_weight > 1):
ABC[result['player_name']] = result['player_surname']
else:
pass
else:
pass
else:
pass
print('*************ABC***************', ABC)
finallist = []
for name in ABC.keys():
finallist.append([name, ABC[name]])
print('*************finallist***************', finallist)
A) Possible bugs:
Maybe you forgot to initialize some variables in the loop for Weight. (your intention was not clear to me)
Other possible problem could be combined tabs and spaces. The code is incorrectly indented after you have pasted it to Stackoverflow. Maybe your editor has a different tab size, maybe Python2 interpreted it as valid, but not how you see it in the editor. Try to run python with -t option, to see warnings if the interpreted logic depends on the tab size. The recommended code style for Python is to not use TABs and to fix all indents to multiples of 4 spaces. The best editor setting for Python is to automatically expand all tabs to spaces.
B) optimizations:
very important
finallist simplified from many database requests to one request:
finallist = list(
Profile.objects.filter(player_name__in=DoubleSNames)
.values_list('player_name', 'player_surname')
)
less important optimization
simplify MyResults.objects.all() to a request with less data rows
results_list = MyResults.objects.filter(
averrage__gt=50,
second_score__gt=70 - F(first_score),
average__lt=F(first_score) + F(second_score),
first_score__gt=0,
second_score__gt=0.2 * F(first_score),
)
ABC.extend(results_list.values_list('player_name', flat=True))
It shouldn't be done before the view will be slow, because readability counts and maybe this will be not the bottle neck.
Disadvantages:
The expression for increase with Case() When() functions would be bad readable. Everything is reformulated, but it is still less readable than a filter on plain Python list.
EDIT:
I accept that you forgot to set the primary key and foreign keys that suggested #Houda, how is normal in Django and that it can be too late to allow Django to add indexes to these tables.
If all data from Profile and Weight can fit in the memory then you can easily map it by a dictionary, otherwise you can filter it by individual names as you did originally or to load them to the memory by a subset of players.
from collections import Counter
profile_map = {x.player_name: x for x in Player.objects.all()}
weight_map = {x.player_name: x for x in Weight.objects.all()}
totals_map = {} # like rows: player, columns: year
ABC = []
for MyResults in [[Results_2019, Results_2018 ]:
results_list = (
MyResults.objects
.annotate(
increase=F('second_score') / F('first_score'),
total=F('second_score') + F('first_score')
)
.filter(
increase__gt=0.2,
total__gt=average_score,
# ... possible more filters
)
)
year_str = MyResults._meta.model_name[-4:]
for result in results_list:
player_name = result.player_name
player = profile_map[player_name]
weight = weight_map[player_name]
weight_year = vars(weight)['year' + year_str[-2:]]
score_weight = result.first_score / weight_year
totals_map.setdefault(player_name, {})[year_str] = result.total
if score_weight > 30 and player.sport_type not in ['football']:
ABC.append(player_name)
counter = Counter(ABC)
DoubleSNames = {name for name, count in counter.items() if count == 2}
finallist = []
for player_name in DoubleSNames:
totals = totals_map['player_name']
total2018 = totals.get('2018', 0)
total2019 = totals.get('2019', 0)
if totals2018 > 0 and total2019 / total2018 > 0.05:
player = player_map[player_name]
finallist.append([player.player_name, player.player_surname])
(It is not an advanced question about django-queryset now, but how to simulate a database relation by Python.)
model.py
from django.db import models
class Profile(models.Model):
player_name = models.CharField(max_length=150)
player_surname = models.CharField(max_length=200)
sport_type = models.CharField(max_length=200)
class Results2019(models.Model):
player_name = models.CharField(max_length=150)
first_score = models.DecimalField(decimal_places=2, max_digits=5, null=True, blank=True,)
second_score = models.DecimalField(decimal_places=2, max_digits=5, null=True, blank=True,)
average_score = models.DecimalField(decimal_places=2, max_digits=5, null=True, blank=True,)
increase = models.BooleanField(null=False, blank=False, default=False, editable=False)
total = models.BooleanField(null=False, blank=False, default=False, editable=False)
def save(self, *args, **kwargs):
if self.second_score / self.first_score > 0.2:
self.increase = 1
else:
self.increase = 0
if self.second_score + self.first_score > self.average_score:
self.total = 1
else:
self.total = 0
super().save(*args, **kwargs)
class Results2018(models.Model):
player_name = models.CharField(max_length=150)
first_score = models.DecimalField(decimal_places=2, max_digits=5, null=True, blank=True,)
second_score = models.DecimalField(decimal_places=2, max_digits=5, null=True, blank=True,)
average_score = models.DecimalField(decimal_places=2, max_digits=5, null=True, blank=True,)
increase = models.BooleanField(null=False, blank=False, default=False, editable=False)
total = models.BooleanField(null=False, blank=False, default=False, editable=False)
def save(self, *args, **kwargs):
if self.second_score / self.first_score > 0.2:
self.increase = 1
else:
self.increase = 0
if self.second_score + self.first_score > self.average_score:
self.total = 1
else:
self.total = 0
super().save(*args, **kwargs)
class Weight(models.Model):
player_name = models.CharField(max_length=150)
year19 = models.DecimalField(decimal_places=2, max_digits=5, null=True, blank=True,)
year18 = models.DecimalField(decimal_places=2, max_digits=5, null=True, blank=True,)
views.py
ABC = {}
weight_dict = defaultdict(dict)
player_dict = {}
for player in Profile.objects.values('player_name', 'player_surname'):
player_dict[player['player_name']] = player['player_surname']
for wt in Weight.objects.values():
weight_dict[wt['player_name']] = {'year19': wt['year19'], 'year18': wt['year18']}
for MyResults in [[Results2019, 'year19'], [Results2018, 'year18']]:
results_list = MyResults[0].objects.\
filter(increase__exact=True, total__exact=True).values('player_name', 'first_score')
for t in results_list:
if t['player_name'] in ABC.keys():
pass
elif float(t['first_score']) / float(weight_dict[t['player_name']][MyResults[1]]) > 30:
ABC[t['player_name']] = player_dict[t['player_name']]
finallist = ABC.items()

Django get_or_create() duplicates in db

Using Django 1.11.6, MySql
I`m importing uniq only data rows from CSV file (~530 rows).
After 1st import - all 530 records updated to the DB.
If I import this file 2d time and ~30 last records will be updated to DB.
Get data:
obj.account = int(ready_item[0].replace("\"","").replace("*",""))
pai_obj.reporting_mask = str(ready_item[0].replace("\"","").replace("*",""))
pai_obj.group = ready_item[1].replace("\"","")
pai_obj.location = ready_item[2].replace("\"","")
pai_obj.terminal = ready_item[4].replace("\"","")
pai_obj.settlement_type = ready_item[5].replace("\"","")
pai_obj.settlement_date = datetime_or_none(report_data)
pai_obj.amount = float_or_none(ready_item[6].replace("\"","").replace("$","").replace(",",""))
data.append(pai_obj)
Import vie get_or_create():
for record in data:
Accountmode.objects.get_or_create(
account=record.account,
reporting_mask=record.reporting_mask,
group=record.group,
location=record.location,
terminal=record.terminal,
settlement_type=record.settlement_type,
amount=record.amount,
defaults={'settlement_date': record.settlement_date})
The Model:
class Accountmode(models.Model):
account = models.IntegerField(blank=True, default=0)
reporting_mask = models.IntegerField(blank=False, default=0)
group = models.CharField(max_length=1024, blank=True, null=True)
location = models.CharField(max_length=1024, blank=True, null=True)
settlement_date = models.DateField(null=True)
terminal = models.CharField(max_length=1024, blank=False, null=True)
settlement_type = models.CharField(max_length=1024, blank=False, null=True)
amount = models.DecimalField(max_digits=25, decimal_places=2)
created_date = models.DateTimeField(default=datetime.now, blank=True)
As I know, get_or_create() should check if data already exist first and create new record if Not. Why get_or_create() pass some records?
The case was about Flout values with +3 symbols after come (12,012).
Those values were duplicating each time the user import same file.
Next solution was found:
1. Save amount and other values at str during file rows parsing.
obj.account = int(ready_item[0].replace("\"","").replace("*",""))
pai_obj.reporting_mask = str(ready_item[0].replace("\"","").replace("*",""))
pai_obj.group = ready_item[1].replace("\"","")
pai_obj.location = ready_item[2].replace("\"","")
pai_obj.terminal = ready_item[4].replace("\"","")
pai_obj.settlement_type = ready_item[5].replace("\"","")
pai_obj.settlement_date = datetime_or_none(report_data)
pai_obj.amount = *str*(ready_item[6].replace("\"","").replace("$","").replace(",",""))
data.append(pai_obj)

Django filter only on aggregate/annotate

I'm trying to construct a fairly complicated Django query and I'm not making much progress. I was hoping some wizard here could help me out?
I have the following models:
class Person(models.Model):
MALE = "M"
FEMALE = "F"
OTHER = "O"
UNKNOWN = "U"
GENDER_CHOICES = (
(MALE, "Male"),
(FEMALE, "Female"),
(UNKNOWN, "Other"),
)
firstName = models.CharField(max_length=200, null=True, db_column="firstname")
lastName = models.CharField(max_length=200, null=True, db_column="lastname")
gender = models.CharField(max_length=1, choices=GENDER_CHOICES, default=UNKNOWN, null=True)
dateOfBirth = models.DateField(null=True, db_column="dateofbirth")
dateInService = models.DateField(null=True, db_column="dateinservice")
photo = models.ImageField(upload_to='person_photos', null=True)
class SuccessionTerm(models.Model):
originalName = models.CharField(max_length=200, null=True, db_column="originalname")
description = models.CharField(max_length=200, blank=True, null=True)
score = models.IntegerField()
class Succession(model.Model):
position = models.ForeignKey(Position, to_field='positionId', db_column="position_id")
employee = models.ForeignKey(Employee, to_field='employeeId', db_column="employee_id")
term = models.ForeignKey(SuccessionTerm)
class Position(models.Model):
positionId = models.CharField(max_length=200, unique=True, db_column="positionid")
title = models.CharField(max_length=200, null=True)
# There cannot be a DB constraint, as that would make it impossible to add the first position.
dottedLine = models.ForeignKey("Position", to_field='positionId', related_name="Dotted Line",
null=True, db_constraint=False, db_column="dottedline_id")
solidLine = models.ForeignKey("Position", to_field='positionId', related_name="SolidLine",
null=True, db_constraint=False, db_column="solidline_id")
grade = models.ForeignKey(Grade)
businessUnit = models.ForeignKey(BusinessUnit, null=True, db_column="businessunit_id")
functionalArea = models.ForeignKey(FunctionalArea, db_column="functionalarea_id")
location = models.ForeignKey(Location, db_column="location_id")
class Employee(models.Model):
person = models.OneToOneField(Person, db_column="person_id")
fte = models.IntegerField(default=100)
dataSource = models.ForeignKey(DataSource, db_column="datasource_id")
talentStatus = models.ForeignKey(TalentStatus, db_column="talentstatus_id")
retentionRisk = models.ForeignKey(RetentionRisk, db_column="retentionrisk_id")
retentionRiskReason = models.ForeignKey(RetentionRiskReason, db_column="retentionriskreason_id")
performanceStatus = models.ForeignKey(PerformanceStatus, db_column="performancestatus_id")
potential = models.ForeignKey(Potential, db_column="potential_id")
mobility = models.ForeignKey(Mobility, db_column="mobility_id")
currency = models.ForeignKey(Currency, null=True, db_column="currency_id")
grade = models.ForeignKey(Grade, db_column="grade_id")
position = models.OneToOneField(Position, to_field='positionId', null=True,
blank=True, db_column="position_id")
employeeId = models.CharField(max_length=200, unique=True, db_column="employeeid")
dateInPosition = models.DateField(null=True, db_column="dateinposition")
Now, what I want is for each employee to get the position title, the person's name, and for each succession term (of which there are three) how many times the position of that employee is in the succession table, and the number of times each of these employees occurs in the successors table. Above all, I want to do all of this in a singe query (or more specifically, a single Django ORM statement), as I'm doing this in a paginated way, but I want to be able to order the result on any of these columns!
So far, I have this:
emps = Employee.objects.all()
.annotate(ls_st=Count('succession__term'))
.filter(succession__term__description="ShortTerm")
.order_by(ls_st)
.prefetch_related('person', 'position')[lower_limit:upper_limit]
This is only one of the succession terms, and I would like to extend it to all terms by adding more annotate calls.
My problem is that the filter call works on the entire query. I would like to only filter on the Count call.
I've tried doing something like Count(succession__term__description'="ShortTerm") but that doesn't work. Is there any other way to do this?
Thank you very much in advance,
Regards,
Linus
So what you want is a count of each different type of succession__term? That is pretty complex, and I don't think you can do this with the built in django orm right now. (unless you did a .extra() query)
In django 1.8, I believe you will be able to do it with the new Query Expressions (https://docs.djangoproject.com/en/dev/releases/1.8/#query-expressions). But of course 1.8 isn't released yet, so that doesn't help you.
In the meantime, you can use the very handy django-aggregate-if package. (https://github.com/henriquebastos/django-aggregate-if/, https://pypi.python.org/pypi/django-aggregate-if)
With django-aggregate-if, your query might look like this:
emps = Employee.objects.annotate(
ls_st=Count('succession__term', only=Q(succession__term__description="ShortTerm")),
ls_lt=Count('succession__term', only=Q(succession__term__description="LongTerm")), # whatever your other term descriptions are.
ls_ot=Count('succession__term', only=Q(succession__term__description="OtherTerm"))
)
.order_by('ls_st')
.prefetch_related('person', 'position')[lower_limit:upper_limit]
Disclaimer: I have never used django-aggregate-if, so I'm not entirely sure if this will work, but according the the README, it seems like it should.

Categories