多对多关系和函数参数的默认值

时间:2014-06-11 23:12:12

标签: database django python-2.7 django-models

我有一个使用Django数据库模型建模系统的课程。在那个课程中,我有几个多对多的关系:

class GroundStationChannel(models.Model):

    identifier = models.CharField('Unique identifier', max_length=30, unique=True)
    modulations = models.ManyToManyField(AvailableModulations)
    bitrates = models.ManyToManyField(AvailableBitrates)

我创建了以下额外的外部静态函数,以帮助我在测试期间从数据库创建/删除这些模型:

def gs_add_channel(gs, band, gs_ch_id, modulations=None,
    bitrates=AvailableBitrates.objects.all()):

    if modulations is None:
        modulations = AvailableModulations.objects.all()

    o = GroundStationConfiguration.objects.add_channel(
        gs_identifier=gs.identifier, identifier=gs_ch_id, band=band,
        modulations=modulations,
        bitrates=bitrates,
    )

    o.save()
    gs.channels.add(o)
    gs.save()

使用' bitrates = AvailableBitrates.objects.all()'引发以下异常我称之为该功能的第二时间:

IntegrityError: (1452, 'Cannot add or update a child row: a foreign key constraint fails \
    (`test_satnet_db`.`configuration_groundstationchannel_bitrates`, 
    CONSTRAINT`availablebitrates_id_refs_id_e5ed4ff5`
    FOREIGN KEY (`availablebitrates_id`)
    REFERENCES `configuration_availablebitra)')

虽然如果我没有提供默认值但是我在函数内初始化它们(比如 modulations 输入参数),则不会引发异常。

我做错了什么?

(add_channel代码):

类GroundStationConfigurationManager(models.Manager):

def add_channel(self, gs_identifier=None, identifier=None, band=None,
                modulations=None, bitrates=None, bandwidths=None, polarizations=None):

    gs = self.get(identifier=gs_identifier)
    gsch = GroundStationChannel.objects\
        .create(identifier=identifier,
                band=band,
                modulations=modulations,
                bitrates=bitrates,
                bandwidths=bandwidths,
                polarizations=polarizations)
    gs.channels.add(gsch)
    gs.save()
    return gsch

(可用比特代码):

class AvailableBitrates(models.Model):
    bitrate = models.IntegerField('Bitrate (bps)')

1 个答案:

答案 0 :(得分:1)

看看这段代码:

>>> import random
>>> random.randint(1,1000)
320
>>> random.randint(1,1000)
153
>>> def r( n=random.randint(1,1000) ):
...    print n
... 
>>> r()
543
>>> r()     #<------ n not re-evaluate
543
>>> r()     #<------ n not re-evaluate
543

如您所见,parm n仅被评估一次。

在您的代码中:

def gs_add_channel(gs, band, gs_ch_id, modulations=None,
    bitrates=AvailableBitrates.objects.all()):

bitrates仅评估一次,这意味着您可以从数据库中删除比特率,但值将保留在bitrates parm 中。这会引发外键错误,因为它试图插入一个不在数据库中的值。像使用modulations参数一样修复它。