一对一类不更新在Django:提供完整性错误

问题描述 投票:0回答:1

我是比较新的Django和已经有点挣扎。这些都是我在下面三种模式:

class Site(models.Model):
    siteID = models.CharField(max_length=255, primary_key=True)

class EndDevice(models.Model):
    class Meta:
        unique_together = ("edevID", "siteID")

    edevID = models.CharField(max_length=255) 
    siteID = models.ForeignKey(Site, on_delete=models.CASCADE)
    deviceCategory = models.BigIntegerField()

class ThirdCombi(models.Model):
    siteID = models.OneToOneField(Site, on_delete=models.CASCADE, primary_key=True)
    endDevice = models.TextField()   

我试图让其中一个的siteID显示所有edevID,这是这里的第三种模式的表。这样确实可以使用以下serializers.py

class CombiSerializer(serializers.ModelSerializer):
    class Meta:
        model = ThirdCombi
        fields = ("siteID", "endDevice")

    def serialize(devices):
        d_list = []
        fields = ['edevID', 'siteID', 'deviceCategory']
        for device in devices:
            d_list.append(model_to_dict(device, fields=fields))
        return d_list

而views.py如下:

class CombiView(generics.RetrieveUpdateDestroyAPIView):
    queryset = ThirdCombi.objects.all()
    serializer_class = CombiSerializer
    def get(self, request, *args, **kwargs):      
        try:
            s1 = Site.objects.get(siteID=kwargs["pk"])
            devices = EndDevice.objects.filter(siteID=s1) 
            a_site, created = ThirdCombi.objects.get_or_create(siteID=s1, endDevice=CombiSerializer.serialize(devices))
            return Response(CombiSerializer(a_site).data)
        except Site.DoesNotExist:
            return Response(
                data={
                    "message": "Site with id: {} does not exist".format(kwargs["pk"])},
                status=status.HTTP_404_NOT_FOUND)

但是,一旦存在EndDevice更新和我重装它给了我一个完整的错误页面,如果我把一个例外,完整性错误,我不能看到EndDevice所做的修改体现在ThirdCombi。我知道为什么会出现完整性错误,因为的siteID已经存在,并试图使一个新的。我不知道如何清除,以避免完整性错误旧的。

任何帮助会以更新的第三个表可以理解的。谢谢。

python django
1个回答
1
投票

在短:使用update_or_createget_or_create代替。

ThirdCombi.objects.update_or_create(siteID=s1, defaults={"endDevice":CombiSerializer.serialize(devices)})

到底部完全更新的代码。

我知道为什么会出现完整性错误,因为的siteID已经存在,并试图使一个新的。

你是对的。

get_or_create:创建一个新的对象,如果它没有找到一个与传递的参数。

OneToOneField:如果你有一个模型Site并与ThirdCombi一个OneToOneField另一个模型Site,这意味着ThirdCombi只能每Site最大的一个对象

问题是你要创建的每ThirdCombi请求新get

请注意:

最初,有2个装置的网站s1

s1 = Site.objects.get(siteID=kwargs["pk"])
devices = EndDevice.objects.filter(siteID=s1) #2 devices
a_site, created = ThirdCombi.objects.get_or_create(siteID=s1, endDevice=CombiSerializer.serialize(devices)) #2 devices serialized "d1, d2"

现在,get_or_create创造了S1新ThirdCombi对象,因为对于S1没有ThirdCombi对象最初。让创建的对象是third_combi1

但是,一旦存在EndDevice更新和我重新加载页面

你看,你已经更新了EndDevice。现在再次观察:

我们已经有网站:s1,EndDevices:d1, d2和ThirdCombi:为third_combi1 s1。我们不能再有一个third_combi2s1

既然你更新EndDevices,让当前更新EndDevices是:d1, d2, d3

s1 = Site.objects.get(siteID=kwargs["pk"])
devices = EndDevice.objects.filter(siteID=s1) #3 devices
a_site, created = ThirdCombi.objects.get_or_create(siteID=s1, endDevice=CombiSerializer.serialize(devices)) #2 devices serialized "d1, d2, d3"

这里的问题是get_or_create没有找到与“D1,D2,D3”的对象。因此,它试图创建另一个third_combi2d1, d2, d3“S1”。因此,完整性错误。

相反,使用update_or_create

update_or_create:更新如果与给定参数的对象存在,否则创建。

你的最终代码应该是:

s1 = Site.objects.get(siteID=kwargs["pk"])
devices = EndDevice.objects.filter(siteID=s1) #2 devices
a_site, created = ThirdCombi.objects.update_or_create(siteID=s1, defaults={"endDevice":CombiSerializer.serialize(devices)})

在这里,如果没有与ThirdCombi一个siteId=s1对象,然后与那些提供更新其endDevice场。否则,创建与给定数据的新ThirdCombi对象。

© www.soinside.com 2019 - 2024. All rights reserved.