简体   繁体   中英

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 used

Problem Statement: I am using Django admin to manage many tables, some of which have many-to-many relationships. I am unable to save new records in tables (models) that have manytomany fields defined. I am able to render the add form just fine. The problem is only upon trying to save the record. I do not have the same problem when updating an existing record.

Using the models below, I receive the following error: 'Bout' instance needs to have a primary key value before a many-to-many relationship can be used.

The Bout model has a many-to-many relationship with the Equipment model. The BoutEquipment model is the intermediate model.

I've researched this problem high and low on StackOverflow and via Google, but am thus far unable to find a solution.

Disclosure: I'm new to Django and new-ish to Python. I'm hopeful that there's a relatively simple solution to this problem.

Thanks in advance.

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')
          )

A manytomany field in django is a join table between the two models you want to connect to each other.

This happens on SQL level, so both models have to exist in the database.

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 :)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM