0

I am building a student test results template but am having a problem. Currently I have created 2 tests (Maths and Spelling) in my Tests model. The problem is, if I enter the data (scores) for the second test (Spelling) for a student first, the score get incorrectly placed in the template - the score gets placed in the Maths column and not the Spelling column. It gets corrected/moved into the spelling column as soon as I enter the same student’s name in the Maths test. It is a minor issue, but the result still is being put in the wrong place and I don’t know why.

I must be doing something wrong. I am missing some sort of filtering I guess. Hopefully the code below will help explain it further. Thanks.

Models.py

    class Student(models.Model):
        first = models.CharField(max_length=100)
        last = models.CharField(max_length=100)
        gender = models.CharField(max_length=1)
        teacher = models.ForeignKey(Teacher)

        def __unicode__(self):
              return "%s %s" % (self.first, self.last)


    class Test(models.Model):
        name = models.CharField(max_length=100)
        Out_of = models.IntegerField(null=True, blank=True)

        def __unicode__(self):
            return self.name

        class Meta:
            ordering = ['name']



    class Display(models.Model):
        name = models.ForeignKey(Student, related_name='art')
        test = models.ForeignKey(Test)
        one = models.IntegerField(null=True, blank=True)
        two = models.IntegerField(null=True, blank=True)
        three = models.IntegerField(null=True, blank=True)

# views.py
    def test(request):

    return list_detail.object_list(
          request,
          queryset = Student.objects.all(),
          template_name = 'display.html',
          template_object_name = 'results',

# display.html

    <table>

    <tr>
        <th>First</th>
        <th>Name</th>
        <th>Maths</th>
        <th>Spelling</th>
    </tr>
    {% for item in results_list %}

    <tr>
              <td> {{ item.first }} </td>
              <td> {{ item.last }} </td>

        {% for x in item.art.all %}
              <td> {{ x.one }} </td>

        {% endfor %}

    {% endfor %}
        </tr>

    </table>

# admin.py
    class StudentInline(admin.TabularInline):
        model = Display


    class TestAdmin(admin.ModelAdmin):
        inlines = [StudentInline]
4

1 回答 1

0

The problem is you need to somehow order the item.art.all() in same order that of your table columns (ie. math numbers and then spelling). Also need to handle cases when only one of the test result is added. But there isn't straight forward way of achieving this, you can't have foreign key (or relationship) member for ordering in Meta class.

So can have a method in your Display model to return list in preferred order and call it from template.

Sample solution below:

class Student(models.Model):
        first = models.CharField(max_length=100)
        last = models.CharField(max_length=100)
        gender = models.CharField(max_length=1)
        teacher = models.ForeignKey(Teacher)
    def __unicode__(self):
          return "%s %s" % (self.first, self.last)

    #this would return in order as math, spelling
    def get_result_list_in_order(self):
        rlist = []
        for tname in ['math', 'spelling']:
            rtest = self.art.filter(test__name__iexact=tname)
            if rtest:
               rlist.append(rtest[0])  #add the first entry from filtered queryset
               # or do
               #rlist.extend(rtest)
            else
               rlist.append(None)

        return rlist

So what you can in template is

{% for x in item.get_result_list_in_order %}
    <td> {{x.one}} </td>
{% endfor %}
于 2012-09-26T08:28:40.283 回答