Django: how to solve several Foreign key relationship problem?

I’m currently learning Django and making electronic grade book. I am completely stuck after trying everything, but still cannot solve the problem. I will explain in detail and post all the relevant code below.

I need to have two url pages “class_students” and “teacher_current”. The first page is for the teacher to see the list of students of a certain class. The table on this page has “action” column. In every cell of this column there is View button, so that the teacher could be redirected to “teacher_current” page and see the list of current tasks, given to a certain student. On this page there is a “Mark” column, its cells may contain EITHER mark given to this student with link to another page to update or delete this mark OR “Add mark” link to add mark on another page.

Here comes the problem: everything works correctly, except the thing that each mark is related to a Task class via Foreign key and NOT to a Student class. So every student of the same class has the same marks for the same tasks. But it certainly won’t do. Here is all my relevant code:

  1. views.py models.py urls.py: CodePile | Easily Share Piles of Code
  2. relevant_templates: CodePile | Easily Share Piles of Code

What I tried: Firstly I thought I could just check, if each mark related to the student, but not the task, so I changed my teacher_student_current.html like this:

<td>
        {% if task.mark_set.get and task.mark_set.get.student_id == student %}
        <a href="{% url 'mark_update' pk=task.mark_set.get.id %}">{{ task.mark_set.get }}</a>
        {% else %}
        <a href="{% url 'mark_add' pk=student.id rel_task=task.id %}">Add mark</a>
        {% endif %}
    </td>

Adding different marks for the same tasks to different students of the same class works, however their reflection in the table doesn’t work.

I also tried changing many things in the template but frequently got an error get() returned more than one Mark – it returned number! Certainly, as mark is related to a task and not a student any attempts to get mark from a student were a failure.

Afterwards, I tried filtering in views.py with filter and even Q loookups, for instance:

def teacher_student_current(request, pk):
    student = Student.objects.get(pk=pk)
    tasks_queryset = Task.objects.filter(mark__student_id=student).order_by('end_date')[:10]
    current_date = datetime.datetime.now()
    if "btnform1" in request.POST:
        return redirect("/school/student/all/")
    context = {
        "student": student,
        "current_date": current_date,
        "tasks_queryset": tasks_queryset,
    }
    return render(request, "teacher_student_current.html", context)

or

def teacher_student_current(request, pk):
    student = Student.objects.get(pk=pk)
    tasks_queryset = Task.objects.filter(
        Q(mark__student_id=None) |
        Q(mark__student_id=student)
    ).order_by('end_date')[:10]
    current_date = datetime.datetime.now()
    if "btnform1" in request.POST:
        return redirect("/school/student/all/")
    context = {
        "student": student,
        "current_date": current_date,
        "tasks_queryset": tasks_queryset,
    }
return render(request, "teacher_student_current.html", context)

But nothing helps, because, even if filtration works creating given mark to a certain task is already assigned only to one student of this class. And there is not even such task for another student. I am sure I miss the logic and don’t know how to tackle at all. I will be glad for your help, even if you just advise me what to google.

Suffice it to say this is a non-trivial project with many non-trivial problems. If you’re just learning Django, this will be hard. Since you have many models, I would suggest implementing their detail and list views with templates that display a lot of each item’s information so that you can get the feel for it. Because to get a working gradebook that an actual teacher would use, you are going to need a massive formset that represents the class and every student and every grade for each task that looks like the traditional grid of a paper gradebook and playing with those views will be useful later.

Since you have the student connected to the mark and not the task, you are going to have to follow the relationship from student to mark to task with something like

This shouldn’t work because the default accessor of marks from tasks is mark_set; regardless, you should run the Django shell (python.py shell) and import your models and then run this view’s code manually to check the output errors. and You may want to research reverse foreign keys and the related_name parameters of foreign key relationships. Regardless, in principle, you will need to get the student id, find the marks that belong to that student id for the particular class id, and then get the tasks related to those marks. You may not be able to get them in one step.

Thanks a lot. I will try it

This topic was automatically closed 182 days after the last reply. New replies are no longer allowed.