From 0e8174aacdf5b25bf493c48f23f33f9ed775540b Mon Sep 17 00:00:00 2001 From: Yohann D'ANELLO Date: Mon, 3 Aug 2020 10:50:55 +0200 Subject: [PATCH] :bug: Fix objects with pk 0 --- apps/permission/models.py | 30 +++++++++++++++++++----------- 1 file changed, 19 insertions(+), 11 deletions(-) diff --git a/apps/permission/models.py b/apps/permission/models.py index bf7dabfa..235977bb 100644 --- a/apps/permission/models.py +++ b/apps/permission/models.py @@ -4,12 +4,15 @@ import functools import json import operator +from copy import copy from time import sleep from django.contrib.contenttypes.models import ContentType from django.core.exceptions import ValidationError +from django.core.mail import mail_admins from django.db import models from django.db.models import F, Q, Model +from django.forms import model_to_dict from django.utils.translation import gettext_lazy as _ @@ -38,35 +41,40 @@ class InstancedPermission: if permission_type == self.type: self.update_query() - # Don't increase indexes, if the primary key is an AutoField - if not hasattr(obj, "pk") or not obj.pk: - obj.pk = 0 - oldpk = None - else: - oldpk = obj.pk + obj = copy(obj) + obj.pk = 0 # Ensure previous models are deleted for ignored in range(1000): - if self.model.model_class().objects.filter(pk=obj.pk).exists(): + if self.model.model_class().objects.filter(pk=0).exists(): # If the object exists, that means that one permission is currently checked. # We wait before the other permission, at most 1 second. sleep(0.001) continue break - for o in self.model.model_class().objects.filter(pk=obj.pk).all(): + for o in self.model.model_class().objects.filter(pk=0).all(): o._force_delete = True Model.delete(o) + # An object with pk 0 wouldn't deleted. That's not normal, we alert admins. + msg = "Lors de la vérification d'une permission d'ajout, un objet de clé primaire nulle était "\ + "encore présent.\n"\ + "Type de permission : " + self.type + "\n"\ + "Modèle : " + str(self.model) + "\n"\ + "Objet trouvé : " + str(model_to_dict(o)) + "\n\n"\ + "--\nLe BDE" + mail_admins("[Note Kfet] Un objet a été supprimé de force", msg) + # Force insertion, no data verification, no trigger obj._force_save = True Model.save(obj, force_insert=True) # We don't want log anything obj._no_log = True - ret = self.model.model_class().objects.filter(self.query & Q(pk=obj.pk)).exists() + ret = self.model.model_class().objects.filter(self.query & Q(pk=0)).exists() # Delete testing object obj._force_delete = True Model.delete(obj) - # If the primary key was specified, we restore it - obj.pk = oldpk + with open("/tmp/log", "w") as f: + f.write(str(obj) + ", " + str(obj.pk) + ", " + str(self.model.model_class().objects.filter(pk=0).exists())) return ret if permission_type == self.type: