Django AttributeError:“ ForwardManyToOneDescriptor”对象没有属性<field>

时间:2019-03-31 16:45:19

标签: python django

我在一个应用程序中有4个相关模型:

class AssetType(models.Model):
    id = models.AutoField(primary_key=True)
    type_name = CaseInsUniqueCharField(name='Type Name')
    parent = models.ForeignKey('self', on_delete=models.CASCADE, blank=True, null=True, verbose_name='parent')
    type_field = models.ManyToManyField('AssetField', blank=True)
    history = HistoricalRecords()

    # Return Asset Name for Queries
    def __str__(self):
        return self.type_name

class AssetField(models.Model):
    id = models.AutoField(primary_key=True)
    field_name = CaseInsUniqueCharField(name='Field Name')
    history = HistoricalRecords()

    # Return Field Name for Queries
    def __str__(self):
        return self.field_name

class AssetFieldValue(models.Model):
    id = models.AutoField(primary_key=True)
    value = models.CharField('value', blank=True, max_length=100)
    field = models.ForeignKey('AssetField', on_delete=models.CASCADE, blank=False)
    asset = models.ForeignKey('Asset', on_delete=models.CASCADE, blank=False)
    history = HistoricalRecords()

    # Return '<Asset> - <Value>' for Queries
    def __str__(self):
        return str(self.asset) + "-" + str(self.field) 

class Asset(models.Model):
    id = models.AutoField(primary_key=True)
    asset_type = models.ForeignKey('AssetType', on_delete=models.CASCADE, verbose_name='Type')
    asset_name = models.CharField('Name', max_length=100)
    asset_tag_no = models.CharField('Tag Number', max_length=20, blank=True, null=True)
    asset_manufacturer = models.ForeignKey('AssetManufacturer', on_delete=models.SET_NULL, null=True, blank=True)
    asset_storage_location = models.ForeignKey('self', on_delete=models.SET_NULL, null=True, blank=True)
    asset_list_price = models.PositiveSmallIntegerField('List Price', blank=True, null=True)
    asset_needs_pat = models.BooleanField('Needs Electrical Test', null=True)
    asset_fields = models.ManyToManyField('AssetField', blank=True, editable=False)
    history = HistoricalRecords()

    # Return Asset name for queries
    def __str__(self):
        return self.asset_name

我在Asset类下添加了一个后保存处理程序

    @receiver(post_save, sender=Asset)
def my_handler(sender, **kwargs):
    t = Asset.asset_type
    f = t.type_field.all()
    for i in range(1,f.count()+1):
        Asset.asset_fields.add(f[i-1:i])

应该添加与资产的AssetFields相关的AssetType条记录。当我在django shell中运行以下命令时,我能够成功将关系添加到Asset ManyToMany字段asset_fields

>>> a = Asset.objects.first()
>>> t = a.asset_type
>>> f = t.type_field.all()
>>> for i in range(1, f.count()+1):
...     a.asset_fields.add(f[i-1:i][0]) 

但是,当我通过管理页面保存与外壳程序中使用的t类型相同的资产时,会出现错误:

    AttributeError at /admin/assets/asset/add/
'ForwardManyToOneDescriptor' object has no attribute 'type_field'

我不确定此错误来自何处,因为在外壳中运行了相同的函数而没有任何问题,除非可能我正在处理@reciever错误?有什么想法吗?

1 个答案:

答案 0 :(得分:0)

但是,您在视图中所做的与在shell中所做的不同。在外壳程序中,您可以访问Asset的特定实例上的asset_type。在视图中,您可以在 class 本身上调用它。那没有道理;与shell版本一样,您需要查询或创建实例,然后才能访问其asset_type-并调用asset_fields.add()

我怀疑,因为这是Asset上的信号处理程序,所以您实际上想使用要保存的实例。在这种情况下:

def my_handler(sender, instance, **kwargs):
    t = instance.asset_type
    f = t.type_field.all()

我也无法理解您的循环在做什么。我怀疑你是说:

    for type in t.type_field.all()
        instance.asset_fields.add(t)