Django AttributeError: у объекта 'ForwardManyToOneDescriptor' нет атрибута <field> - PullRequest
0 голосов
/ 31 марта 2019

У меня есть 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, я могу успешно добавить отношения в поле 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 голосов
/ 31 марта 2019

Но вы не делаете то же самое в представлении, как в оболочке. В оболочке вы получаете доступ к asset_type на конкретном экземпляре актива. В представлении вы вызываете его для самого класса . Это не имеет смысла; как и в случае версии оболочки, вам нужно запросить или создать экземпляр, затем вы можете получить доступ к его 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)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...