【问题标题】:Many-to-many relationship and function parameter's default value多对多关系和函数参数的默认值
【发布时间】:2014-08-02 04:03:10
【问题描述】:

我有一个使用 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)')

【问题讨论】:

  • 你能添加你对GroundStationConfiguration.objects.add_channel的定义吗?
  • 另外,您不应将函数调用作为默认值传递。您应该使用无,然后检查它是否为无。如果是,则将其设置为AvailableBitrates.objects.all()。原因是因为默认值将在编译文件时定义,然后在第一次使用时进行评估。在那之后,我相信它会继续返回相同的结果。
  • @schillingt,这就是我找到的解决方案。问题是,第一次评估函数时,正确计算了该输入参数的默认值。在我看来,问题出在数据库中的值上,但我不确定为什么。顺便说一句,函数add_channel是在示例源码中定义的。
  • 你的意思是gs_add_channelGroundStationConfiguration.objects.add_channel一样吗?
  • @schillingt,我刚刚添加了该方法的代码。很抱歉我第一次误解了你的问题。

标签: database django python-2.7 django-models


【解决方案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 参数一样修复它。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-10-12
    • 2013-06-26
    • 1970-01-01
    • 2016-08-06
    • 1970-01-01
    • 1970-01-01
    • 2014-11-13
    相关资源
    最近更新 更多