我在一个应用程序中有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
错误?有什么想法吗?
答案 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)