2
votes

django.db.utils.IntegrityError: la contrainte FOREIGN KEY a échoué

Mes modèles.py

class Status(models.Model):
    name = models.CharField(max_length = 16, blank=True, null=True, default=None)
    is_active = models.BooleanField(default=True)
    created = models.DateTimeField(auto_now_add=True, auto_now=False)
    updated = models.DateTimeField(auto_now_add=False, auto_now=True)

    def __str__(self):
        return "Статус %s" % self.name

Mes vues.py .

Traceback (most recent call last):
  File "C:\Users\Nikita Shuliak\AppData\Local\Programs\Python\Python37- 
 32\lib\site-packages\django-2.1rc1-py3.7.egg\django\core\handlers\exception.py",   line 34, in inner
    response = get_response(request)
  File "C:\Users\Nikita Shuliak\AppData\Local\Programs\Python\Python37-32\lib\site-packages\django-2.1rc1-py3.7.egg\django\core\handlers\base.py", line 126, in _get_response
    response = self.process_exception_by_middleware(e, request)
  File "C:\Users\Nikita Shuliak\AppData\Local\Programs\Python\Python37-32\lib\site-packages\django-2.1rc1-py3.7.egg\django\core\handlers\base.py", line 124, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "C:\Users\Nikita Shuliak\Desktop\NJB\startup\orders\views.py", line 59, in checkout
    order = Order.objects.create(user=user, customer_name=name, customer_phone=phone, status_id=1)
  File "C:\Users\Nikita Shuliak\AppData\Local\Programs\Python\Python37-32\lib\site-packages\django-2.1rc1-py3.7.egg\django\db\utils.py", line 89, in __exit__
    raise dj_exc_value.with_traceback(traceback) from exc_value
  File "C:\Users\Nikita Shuliak\AppData\Local\Programs\Python\Python37-32\lib\site-packages\django-2.1rc1-py3.7.egg\django\db\backends\base\base.py", line 239, in _commit
    return self.connection.commit()
django.db.utils.IntegrityError: FOREIGN KEY constraint failed

L'erreur:

def checkout(request):
    session_key = request.session.session_key
    products_in_basket = ProductInBasket.objects.filter(session_key=session_key, is_active=True)
    form = CheckoutContactForm(request.POST or None)
    if request.POST:
        print(request.POST)
        if form.is_valid():
            print("OK")
            data = request.POST
            name = data.get("name", "34343434")
            phone = data["phone"]
            user, created = User.objects.get_or_create(username=phone, defaults={"first_name": name})

            order = Order.objects.create(user=user, customer_name=name, customer_phone=phone, status_id=1)
            for name, value in data.items():
                if name.startswith("product_in_basket_"):
                    product_in_basket_id = name.split("product_in_basket_")[1]
                    product_in_basket = ProductInBasket.objects.get(id=product_in_basket_id)

                    product_in_basket.nmb = value
                    product_in_basket.order = order
                    product_in_basket.save(force_update=True)

                    ProductInOrder.objects.create(
                        product=product_in_basket.product, 
                        nmb=product_in_basket.nmb, 
                        price_per_item=product_in_basket.price_per_item, 
                        total_price=product_in_basket.total_price, 
                        order=order
                    )

        else:
            print("ERROR")
    return render(request, 'orders/checkout.html', locals())

MODIFICATION DU MODÈLE D'ÉTAT

Peut-être que le problème est là. Le problème est apparu après avoir ajouté du code que vous pouvez voir dans les commentaires. "Cette dernière erreur suggère que le statut avec pk = 1 existe déjà, mais votre erreur précédente suggère le contraire. Veuillez ajouter votre modèle de statut à votre question; voyons s'il y a d'autres conditions à considérer.":

XXX


3 commentaires

Veuillez ajouter le stacktrace d'erreur afin que nous puissions voir quel est le problème réel. Vous avez collé quelques lignes, mais c'est hors contexte et n'aide pas.


De plus, il est très inhabituel d'utiliser null = True avec un CharField . en savoir plus


@Ralf, j'ajoute un suivi complet.


3 Réponses :


0
votes

L'erreur est dans la ligne:

order = Order.objects.create(user=user, customer_name=name, customer_phone=phone, status_id=1)

Vous devez transmettre une instance de statut pour le champ status car il s'agit d'un champ ForeignKey . Le simple fait de définir status_id sur un entier ne fonctionnera pas. Je me tiens corrigé, ça peut marcher; voir ce post .

Votre erreur se produit probablement parce que l'un ou l'autre des utilisateurs ( ou user_id ) ou status (ou status_id ) font référence à des instances qui n'existent pas dans la table de base de données associée.

Êtes-vous sûr qu'il existe un statut avec pk = 1 ? L'opération Status.objects.get (pk = 1) réussit-elle?


13 commentaires

Et que dois-je faire? Comment puis-je réparer cela ?


L'opération Status.objects.get (pk = 1) réussit-elle?


Si l'instance Status avec pk = 1 n'existe pas, vous devez d'abord la créer ou attribuer une autre instance Status à votre nouvelle < code> Instance de commande .


La requête de correspondance d'état n'existe pas


D'accord. Créez un statut avec pk = 1 ou attribuez un statut différent dans Order.objects.create (..., status_id = 1)


J'ai ajouté que: st = Status.objects.create (pk = 1) Et j'ai cette erreur: Type d'exception: IntegrityError Valeur d'exception: La contrainte UNIQUE a échoué: orders_status.id


Je suis vraiment désolé de perdre votre temps. Mais je veux comprendre ce qui se passe et comment résoudre des problèmes comme celui-ci.


Cette dernière erreur suggère que le statut avec pk = 1 existe déjà, mais votre erreur précédente suggère le contraire. Veuillez ajouter votre modèle Status à votre question; permet de voir s'il y a d'autres conditions à considérer.


Veuillez modifier le code dans votre question, le format dans les commentaires ne convient pas au code multi-lignes


J'ajoute un modèle de statut.


Il ne semble y avoir rien d'étrange avec votre modèle Status . Êtes-vous sûr que la ligne Status.objects.get (pk = 1) génère une erreur DoesNotExist ? Ou êtes-vous sûr que Status.objects.create (pk = 1) génère une erreur «Échec de la contrainte UNIQUE»?


Oui. Il montre ceci: django.db.utils.IntegrityError: la contrainte UNIQUE a échoué: orders_status.id Aussi, j'ai essayé de coller ce morceau de code avant cette ligne: if request.POST: Et cela m'a donné une erreur et je n'ai pas pu ouvrir mon checkout.html lors de l'exécution. Edit: De plus, j'ai remarqué que j'avais un problème: pas de table: mainApp_subscriber après l'ajout du code d'état.


Mec, franchement, je ne comprends pas ce que j'ai fait, mais apparemment, je résous le problème. J'ai changé ceci: order = Order.objects.create (user = user, customer_name = name, customer_phone = phone, status_id = 1) pour ceci: order = Order.objects.get_or_create ( user = user, customer_name = name, customer_phone = phone, status_id = 1)



0
votes

Je vois que vous n'avez pas enregistré l'instance "order". ---- order.save ()

Je pense que la solution est de sauvegarder les instaces à sauvegarder.

Aujourd'hui, j'ai eu le même message d'erreur que vous. J'ai réalisé que j'avais oublié d'enregistrer une instance dans mon code. Mon code est différent de votre code, mais je pense que vous valez la peine d'essayer


1 commentaires

Je n'ai pas confiance en l'anglais. L'anglais peut être faux (+ _ +)



1
votes

Essayez de définir le paramètre nommé de db_constraint de models.ForeignKey () sur False (par défaut, son code True >) comme ceci:

status = models.ForeignKey(Status, on_delete=models.PROTECT,db_constraint=False)

Cela a fonctionné pour moi sur un certain projet, le seul problème sera que vous ne pourrez pas assurer l'intégrité de votre base de données (par exemple, savoir si tous les objets Status référencés existent réellement) mais cela a du sens si vous travaillez avec du code hérité. J'espère que cela aide.


0 commentaires