首页 > 解决方案 > 如何使用 Django 自定义模板标签来获取对象的属性?

问题描述

我写了一个自定义标签,它正在工作。那里没问题。但是,虽然模板标签返回了我需要的模型对象,但我无法更进一步获取该对象的属性。如下所示:

模型.py

class ExamScore(models.Model):
    exam_name = models.CharField(max_length=20)
    reading = models.DecimalField(blank=True, null=True, max_digits=5, decimal_places=2)
    uofe = models.DecimalField(blank=True, null=True, max_digits=5, decimal_places=2,
                           verbose_name='use of English')
    writing = models.DecimalField(blank=True, null=True, max_digits=5, decimal_places=2)
    listening = models.DecimalField(blank=True, null=True, max_digits=5, decimal_places=2)
    speaking = models.DecimalField(blank=True, null=True, max_digits=5, decimal_places=2)
    student = models.ForeignKey(Student, on_delete=models.CASCADE)

custom_tags.py

@register.simple_tag
def unique_exam(student_id, exam_name, skill):
    if ExamScore.objects.filter(student_id=student_id, exam_name=exam_name).exists():
        e = ExamScore.objects.get(student_id=student_id, exam_name=exam_name).skill
        return e
    else:
        return ''

模板.html

<input type="number"
       step="0.01" 
       class="score" 
       id="score-re" 
       value="{% unique_exam student.id exam_name 'reading' %}"
       placeholder="36">
 #  the trouble is here where it says 'reading'
 #  I have also tried 'reading' with double quotes and no quotes

在这种情况下,“阅读”是我想要的属性,其他时候是说、听等。这就是为什么我不能对其进行硬编码,而必须将其作为参数传递给标签。

我得到的是:

/teacher/exams/PreCourse/ 处的 AttributeError

“ExamScore”对象没有“技能”属性

回溯特别告诉我问题出在:

第 17 行。e = ExamScore.objects.get(student_id=student_id,exam_name=exam_name).skill

我知道没有属性“技能”,它是一个变量,应该包含 ExamScore 对象属性的名称。本地变量说它确实:

▼ Local vars

变量:值

考试名称:'预科'

技能:“阅读”

学生编号:4

所以,我的问题是如何将技能类型(例如阅读、听力......)分配给变量并将其附加到我的 ExamScore 对象以获取该属性以作为值放入我的表单中?

非常感谢您的帮助!

标签: djangopython-3.x

解决方案


您应该使用内置的getattr ,它用于尝试动态获取属性(强调我的):

返回 object 的命名属性的值。名称必须是字符串。如果字符串是对象属性之一的名称,则结果是该属性的值。例如,getattr(x, 'foobar') 等价于 x.foobar。如果命名属性不存在,则返回默认值(如果提供),否则引发AttributeError 。

在您的自定义标签中,您应该尝试:

@register.simple_tag
def unique_exam(student_id, exam_name, skill):
    if ExamScore.objects.filter(student_id=student_id, exam_name=exam_name).exists():
        e = ExamScore.objects.get(student_id=student_id, exam_name=exam_name)
        e = getattr(e, skill, "")
        return e
    else:
        return ''

推荐阅读