错误:利用自引用外键的方法时,“'NoneType'对象没有属性...”

时间:2018-06-25 23:31:37

标签: django python-3.x django-models

我正在开发自己的第一个Django项目以进行练习,但是遇到了自引用外键的问题。

我有一个名为“ units”的应用,其中有一个models.py:

from django.db import models

class Unit(models.Model):
    name = models.CharField(
        'Unit', 
        max_length=255, 
        blank=True
        )
    quantity_per = models.DecimalField(
        'Quantity Per', 
        max_digits=10, 
        decimal_places=5, 
        default=1
        )
    subunit = models.ForeignKey(
        'self', 
        blank=True, 
        null=True, 
        on_delete=models.SET_NULL, 
        related_name='+', 
        verbose_name="subunit"
        )
    abbreviation = models.CharField(
        'Abbreviation', 
        max_length=255, 
        blank=True
        )

    def unit_factor(self):
        return self.subunit.quantity_per * self.quantity_per

    def __str__(self):
        return self.name

这在我的基本索引模板中是这样指的:

{% load static %}

<link rel="stylesheet" type="text/css" href="{% static 'units/style.css' %}"/>

{% if unit_list %}
  <ul>
    {% for unit in unit_list %}
    <li>{{ unit.name }} - {{ unit.subunit }} - {{ unit.subunit.quantity_per }} - {{ unit.unit_factor }}</li>
    {% endfor %}
  </ul>
{% else %}
  <p>No units are available.</p>
{% endif %}

当我运行服务器并导航到“ units” URL时,出现以下错误:

'NoneType' object has no attribute 'quantity_per'

我认为这与我在与自引用外键相同的类中创建方法以及子实例尚未完全实例化有关吗?但是我确信我缺乏编程知识正在显示。如何在这种关系中正确执行这样的操作?

更新 我将其标记为已解决,但我想根据@ alexandre-cox请求添加视图:

from django.template import loader
from django.views import generic

from .models import Unit

class IndexView(generic.ListView):
    template_name = 'units/index.html'

    def get_queryset(self):
        return Unit.objects.order_by('name')

感谢您的耐心回答!

1 个答案:

答案 0 :(得分:1)

由于您的Unit实例没有任何子代,并且您的代码尝试访问子代的quantity_per属性,因此引发了异常。

因此,如下更改unit_factor()方法,

def unit_factor(self):
    if hasattr(self, 'subunit') and hasattr(self.subunit, 'quantity_per'):
        return self.subunit.quantity_per * self.quantity_per
    return 0  # Default Value

请参阅python内置函数hasattr()