Django AttributeError: 'ForwardManyToOneDescriptor'对象没有属性<field>。

8

我在一个应用程序中有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])

这应该是添加与资产的AssetType相关的AssetFields记录。当我在django shell中运行以下内容时,我成功地将关系添加到资产的多对多字段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]) 

然而,当我通过管理页面保存与shell中使用的相同类型t的资产时,出现以下错误:

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

我不确定这个错误是从哪里引起的,因为相同的函数在shell中运行没有任何问题,除非我处理@reciever时出错了?有什么想法吗?

1个回答

5
但是在视图中与shell中不同。在shell中,您可以访问Asset的特定实例上的asset_type。而在视图中,您需要在类本身上调用它。这没有意义;就像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)

1
我明白了,非常感谢你的帮助 - 添加“instance”解决了主要问题。你的循环比我的更优雅,尽管我认为它应该是“instance.asset_fields.add(type)”。非常感谢! - omar_hussein

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接