【问题标题】:Django admin Trouble saving new records with M2M fields - instance needs to have a primary key value before a many-to-many relationship can be usedDjango admin 使用 M2M 字段保存新记录时遇到问题 - 实例需要有一个主键值才能使用多对多关系
【发布时间】:2013-06-07 15:48:27
【问题描述】:

问题陈述: 我正在使用 Django admin 管理许多表,其中一些表具有多对多关系。我无法在定义了许多字段的表(模型)中保存新记录。我能够很好地呈现添加表单。问题仅在于尝试保存记录。更新现有记录时,我没有同样的问题。

使用以下模型,我收到以下错误:“Bout”实例需要有一个主键值才能使用多对多关系。

Bout 模型与 Equipment 模型具有多对多的关系。 BoutEquipment 模型是中间模型。

我在 StackOverflow 上和通过 Google 对这个问题进行了高深研究,但至今找不到解决方案。

披露:我是 Django 新手,也是 Python 新手。我希望有一个相对简单的解决方案来解决这个问题。

提前致谢。

models.py

class Bout(models.Model):    
boutid = models.AutoField(db_column=u'BoutID', primary_key=True) 
sessionid = models.ForeignKey(Session, db_column=u'SessionID', verbose_name=u'Session') 
activitytypeid = models.ForeignKey(Activitytype, db_column=u'ActivityTypeID', verbose_name=u'Activity Type') 
locationid = models.ForeignKey(Location, db_column=u'LocationID',verbose_name=u'Location') 
equipment = models.ManyToManyField(Equipment, verbose_name=u'Related Equipment', related_name=u'Bout_Equipment', blank=True, null=True) #through = 'BoutEquipment'
intensitymetrics = models.ManyToManyField(Intensitymetric, verbose_name=u'Related Intensity Metrics', related_name=u'Bout_IntensityMetrics', blank=True, null=True) #through = 'BoutIntensitymetric'

def __unicode__(self):
    return u'%s %s' % (self.sessionid, self.activitytypeid)

class Meta:
    db_table = u'app_bout'
    verbose_name = u'Bout'
    verbose_name_plural = u'Bouts'

class Equipment(models.Model):
equipmentid = models.AutoField(db_column=u'EquipmentID', primary_key=True) 
name = models.CharField("Name", max_length=100, db_column=u'Name')
equipmenttypeid = models.ForeignKey(Equipmenttype, db_column=u'EquipmentTypeID', verbose_name = u'Equipment Type') 

def __unicode__(self):
    return self.name

class Meta:
    db_table = u'app_equipment'
    verbose_name = u'Equipment'
    verbose_name_plural = u'Equipment'

class BoutEquipment(models.Model):
id = models.AutoField(db_column=u'id', primary_key=True)
boutid = models.ForeignKey(Bout, db_column=u'Bout_ID') 
equipmentid = models.ForeignKey(Equipment, db_column=u'Equipment_ID') 

def __unicode__(self):
    return self.name

class Meta:
    db_table = u'app_bout_equipments'

admin.py

class EquipmentAdmin(admin.ModelAdmin):
form = EquipmentForm
inlines = [EquipmentShoeInline, EquipmentLogInline]
list_display = ('name','equipmenttypeid','manufacturer','retired','retiredby','retiredon','notes')
fields = (
          'name',
          ('equipmenttypeid','manufacturer'),
          ('retired','retiredby','retiredon'),
          'notes'
          )
class BoutAdmin(admin.ModelAdmin):
form = BoutForm
filter_horizontal = ('equipment','intensitymetrics',)
list_display = ('sessionid','activitytypeid','locationid','sequence','activehand','baddata')
inlines = [BoutDeviceInline,]
fields = (
          ('sessionid','locationid','activitytypeid'),
          'videofilelocation',
          'sequence',
          'activehand',
          'notes',
          'baddata',
          ('equipment','intensitymetrics')
          )

【问题讨论】:

    标签: django django-admin django-orm


    【解决方案1】:

    django 中的manytomany 字段是您要相互连接的两个模型之间的连接表。

    这发生在 SQL 级别,因此两个模型都必须存在于数据库中。

    bout = Bout()
    ...
    
    equipment = Equipment()
    ...
    
    bout.equipment.add(equipment)
    #fails because bout and equipment are not saved
    
    bout.save()
    bout.equipment.add(equipment)
    #fails because equipment is not saved
    
    equipment.save()
    bout.equipment.add(equipment)
    #yay :)
    

    【讨论】:

    • 感谢@Jay 的回复。我想我从概念上理解这个问题。我正在为实施而苦苦挣扎。我是否在模型级别覆盖保存方法?我在 Bout 模型级别使用以下代码进行了尝试。 def save(self): b = Bout() e = Equipment() e.save() b.equipment.add(e) b.save() 'code'
    • 对不起。由于某种原因,我似乎无法将保存方法代码干净地嵌入到上面的评论中。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-10-06
    • 2010-10-24
    • 2013-06-21
    • 1970-01-01
    • 2011-08-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多