rohit1248
rohit1248

Reputation: 181

Using dynamic object filter

I am trying to access names of all the students having marks 100.

def get_names(request):
    students = Result.objects.filter(marks=100)
    student_name = []
    for x in students:
        student_name.append(x.student)
    for x in student_name:
        print (x.name)
    return render(request, 'exam/index.html', {'names': student_name})

When I run this view, 'Student has no attribute '__getitem__'' is displayed on the line print(x.name). I read something about dynamic object filter but cannot figure it out in this case.

Model structure

class Student(models.Model):
    name = models.CharField(max_length=20)
    stream = models.CharField(max_length=20)


class Result(models.Model):
    student = models.ForeignKey(Student, on_delete=models.CASCADE)
    marks = models.IntegerField()

Upvotes: 0

Views: 71

Answers (2)

Paulo Almeida
Paulo Almeida

Reputation: 8061

You would be helping yourself if you used more informative variable names, instead of seemingly going out of your way to come up with confusing ones. In your code snippet:

def get_names(request):
    results = Result.objects.filter(marks=100)
    students = []
    for result in results:
        students.append(result.student)
    for student in students:
        print(student.name)
    return render(request, 'exam/index.html', {'names': student_name})

That said, I don't understand where your Student has no attribute '__getitem__' is coming from, or why it is being printed and not raising an exception. __getitem__ is for accessing items of sequences with integer or slice keys, and you don't seem to be doing that anywhere. From the models you presented here, x (or student in my code) should be a Student instance, and doing print(x.name) should work.

In any case, you could do this in a much simpler way:

def get_names(request)
    students = Student.objects.filter(result__marks=100).distinct()
    return render(request, 'exam/index.html', {'students': students})

Then you can iterate students in the template and acess student.name. If you just want to pass a list of names to the template, you could use values_list('name', flat=True) in the query.

Upvotes: 1

Dharmesh Fumakiya
Dharmesh Fumakiya

Reputation: 2338

If you want to just print the student name

for x in students:
    print(x.student.name)
    student_name.append(x.student)

Upvotes: 0

Related Questions