-1

I want to fill the array 'v' with the number of doctors in each department, I got this error :

v[i]=Doctor.objects.all().filter(idDept__deptName__contains=s.deptName).count()
~^^^

IndexError: list assignment index out of range

views.py

def accueilAdmin(request):
    if not request.user.is_staff:
        return redirect('loginAdmin')
    depts=Department.objects.all()
    v=[]
    i=1
    for s in depts:
        v[i]=Doctor.objects.all().filter(idDept__deptName__contains=s.deptName).count()
        i+=1

models.py

class Department(models.Model):
    deptName = models.CharField(max_length=50, null=False)
    ...
        return self.deptName


class Doctor(models.Model):
    name= models.CharField(max_length=50)
        ...
    idDept = models.ForeignKey(Department, on_delete=models.CASCADE, null=True)
    def __str__(self):
        return self.name

I don't know how to solve it, I would appreciate your help, thank you.

zlydia
  • 17
  • 5
  • Does this answer your question? [Why does this iterative list-growing code give IndexError: list assignment index out of range? How can I repeatedly add (append) elements to a list?](https://stackoverflow.com/questions/5653533/why-does-this-iterative-list-growing-code-give-indexerror-list-assignment-index) – Abdul Aziz Barkat Jun 24 '23 at 09:25
  • Nope, I tried Willem VO supports mod strike's suggestion and it worked. Thank you. – zlydia Jun 24 '23 at 09:33

2 Answers2

0

Indexes start at 0, you can append to the list with:

def accueilAdmin(request):
    if not request.user.is_staff:
        return redirect('loginAdmin')
    depts = Department.objects.all()
    v = []
    for s in depts:
        v.append(
            Doctor.objects.all()
            .filter(idDept__deptName__contains=s.deptName)
            .count()
        )
        i += 1

But this is likely all not necessary and inefficent, you can just annotate your Departments with the number of Doctors:

from django.contrib.auth.decorators import user_passes_test
from django.db.models import Count
from django.urls import reverse_lazy


@user_passes_test(lambda u: u.is_staff, 'loginAdmin')
def accueil_admin(request):
    depts = Department.objects.annotate(num_doctors=Count('doctor'))
    # …

The Department objects in depts will then have an extra attribute .num_doctors with the number of related Doctors. This is done in the same query, hence it reduces the amount of queries enormously:


Note: Functions are normally written in snake_case, not PascalCase, therefore it is advisable to rename your function to accueil_admin, not accueilAdmin.

Willem Van Onsem
  • 443,496
  • 30
  • 428
  • 555
0

i'm a newbie, but maybe my thoughts will help you: lists enumeration starts with '0', in views.py you assign value to 'v' equal to empty list, so there is no elements there(not '1st' elem nor '0'), try not to refer the index of element(v[i]) but v.append, not good solution, but it can temporary help to debug your app: when assing value to/create 'v' -make it like list with existing elements: v = list(range(1000))