简体   繁体   English

django.db.utils.IntegrityError: FOREIGN KEY 约束在 django 中失败

[英]django.db.utils.IntegrityError: FOREIGN KEY constraint failed in django

i keep on getting the above error on creating a new user model when creating users using postman here is my code.在使用 postman 创建用户时,我在创建新用户 model 时不断收到上述错误,这是我的代码。

from django.contrib.auth.models import AbstractBaseUser, BaseUserManager
from django.core.validators import RegexValidator
from django.db import models
from django.db.models.signals import post_save
from django.dispatch import receiver
from rest_framework.authtoken.models import Token
from wallet.models import Transfer, Payment, Transaction, Wallet


class UserManager(BaseUserManager):
    use_in_migrations = True

    def create_user(self, name, phone, password,pin_code,confirm_pin,expected_delivery_month,email=None):
        user = self.model(name=name,phone=phone, email=email,pin_code=pin_code,confirm_pin=confirm_pin,
            expected_delivery_month=expected_delivery_month
        )
        user.set_password(password)
        user.save(using=self._db)
        return user

    def create_superuser(self,name,phone,password,pin_code,expected_delivery_month,email=None, ):
        user = self.create_user(name,phone,password,email,pin_code,expected_delivery_month)

        user.is_admin = True
        user.save(using=self._db)
        return user


class User(AbstractBaseUser):
    name = models.CharField(max_length=120)
    phone_regex = RegexValidator(regex=r'^\+?1?\d{9,15}$',
                                 message="Phone number must be entered in the format +256706626855. Up to 10 digits allowed.")
    phone = models.CharField('Phone', validators=[
                             phone_regex], max_length=17, unique=True, null=False)
    email = models.EmailField(
        verbose_name='email address', max_length=255, unique=True, null=True)
    is_admin = models.BooleanField(default=False)
    #now i need to add the pin coz its what am going to base on for the user creattion as the OTP
    pin_code = models.IntegerField(blank=False,unique=True)#vital here
    confirm_pin = models.IntegerField(blank=False)#this field here is to help in the confirmation of the pin

    expected_delivery_month = models.CharField(blank=False,default='january',max_length=20)
    objects = UserManager()

    USERNAME_FIELD = 'phone'
    REQUIRED_FIELDS = ['name','pin_code']

    
    def __str__(self):
        return self.name


    class Meta:
        unique_together = ("phone","pin_code")#since i need each phone number to have a unique pin code

    @property
    def is_staff(self):
        "Is the user a member of staff?"
        return self.is_admin

    def has_perm(self,perm,obj=None):
        """Does the user have aspecific permission"""
        return True

    def has_module_perms(self,app_label):
        """Does the user have permissions to view thw app `app_label` """
        return True

@receiver(post_save, sender=User)
def create_wallet(sender, instance, **kwargs):
    """
        Create a wallet for every new user
    """
    Token.objects.create(user=instance)
    transfer = Transfer(
        transferred_to=instance, transferred_from=instance,transfer_reason='Initial Transfer',amount=0
    )
    transfer.save()
    transaction = Transaction(transfer_id=transfer,amount=transfer.amount)
    transaction.save()
    wallet = Wallet(balance=0, owner=instance, latest_transaction=transaction)
    wallet.save()


however on carrying out some tests in development using Postman i keep on getting the error below.但是,在使用 Postman 在开发中进行一些测试时,我不断收到以下错误。

 return self.connection.commit()
django.db.utils.IntegrityError: FOREIGN KEY constraint failed
[07/Apr/2021 09:19:04] "POST /user/register/%0A HTTP/1.1" 500 19194
Performing system checks...

i tried making some changes by adding db_constraint=False in the models related to the User model however still in vain.the following are the models with a foreignKey rxnship to the user model.我尝试通过在与用户 model 相关的模型中添加 db_constraint=False 来进行一些更改,但仍然徒劳无功。以下是用户 model 具有外键 rxnship 的模型。

import uuid
from django.conf import settings
from django.db import models
from django.utils import timezone
from django.utils.translation import gettext_lazy as _

# Create your models here.

class Payment(models.Model):
    Statuses = (
        ('PENDING', 'Pending'),
        ('COMPLETE', 'Complete'),
        ('FAILED', 'Failed'),
    )
    Categories = (
        ('TOP_UP','Top Up'),
        ('WITHDRAW','Withdraw')
    )
    id = models.UUIDField(primary_key=True, default=uuid.uuid4,editable=False)
    status = models.CharField(max_length=2, choices=Statuses,default="PENDING")
    transaction_ref = models.UUIDField(default=uuid.uuid4)
    paid_at = models.DateTimeField(null=True)
    amount = models.IntegerField()
    user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.DO_NOTHING,db_constraint=False)
    category = models.CharField(max_length=2,choices=Categories,default="TOP_UP")

    def __str__(self) -> str:
        return str(self.id)

class Transfer(models.Model):
    id = models.UUIDField(primary_key=True,default=uuid.uuid4,editable=False)
    transferred_to = models.ForeignKey(
        settings.AUTH_USER_MODEL,on_delete=models.DO_NOTHING,related_name='transferred_to',db_constraint=False)
    transferred_from = models.ForeignKey(
        settings.AUTH_USER_MODEL, on_delete=models.DO_NOTHING,related_name='transferred_from',db_constraint=False)
    amount = models.IntegerField()
    transfer_reason = models.CharField(max_length=200)

    def __str__(self) -> str:
        return str(self.id)

class Transaction(models.Model):
    id=models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    amount = models.IntegerField(editable=False)
    payment_id = models.ForeignKey(Payment,blank=True, on_delete=models.CASCADE, null=True)
    transfer_id = models.ForeignKey(Transfer, blank=True,null=True, on_delete=models.CASCADE)

    def __str__(self) -> str:
        return str(self.id)

class Wallet(models.Model):
    id=models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    balance = models.IntegerField()
    owner = models.ForeignKey(settings.AUTH_USER_MODEL,on_delete=models.CASCADE,db_constraint=False)
    latest_transaction = models.ForeignKey(Transaction, on_delete=models.CASCADE)
    created_at = models.DateTimeField(default=timezone.now,editable=False)

    class Meta:
        ordering = ['created_at']

    def __str__(self) -> str:
        return str(self.id)

notice the db_constraint=False i have added on every model with a ForeignKey rxnship to the user model.请注意 db_constraint=False 我在每个 model 上添加了一个 ForeignKey rxnship 给用户 model。 Note: Am using my User model as the custom user model, and using sqlite3 as my database注意:我使用我的用户 model 作为自定义用户 model,并使用 sqlite3 作为我的数据库

here is the test as in postman这是 postman 中的测试

{
    "name":"shifa",
    "phone":"0705674532",
    "pin_code":"2011",
    "confirm_pin":"2011",
    "expected_delivery_month":"December"
}

its a post request and returns the following error.它是一个发布请求并返回以下错误。

IntegrityError at /user/register/

FOREIGN KEY constraint failed

Request Method: POST
Request URL: http://127.0.0.1:8000/user/register/%0A
Django Version: 2.1
Python Executable: /home/utopia/pregweb/bin/python
Python Version: 3.6.8
Python Path: ['/home/utopia/pregweb/pregnew', '/usr/lib/python36.zip', '/usr/lib/python3.6', '/usr/lib/python3.6/lib-dynload', '/home/utopia/pregweb/lib/python3.6/site-packages']
Server time: Wed, 7 Apr 2021 09:19:04 +0000
Installed Applications:
['django.contrib.admin',
 'django.contrib.auth',
 'django.contrib.contenttypes',
 'django.contrib.sessions',
 'django.contrib.messages',
 'django.contrib.staticfiles',
 'rest_framework.authtoken',
 'rest_framework',
 'user',
 'wallet']
Installed Middleware:
['django.middleware.security.SecurityMiddleware',
 'django.contrib.sessions.middleware.SessionMiddleware',
 'django.middleware.common.CommonMiddleware',
 'django.middleware.csrf.CsrfViewMiddleware',
 'django.contrib.auth.middleware.AuthenticationMiddleware',
 'django.contrib.messages.middleware.MessageMiddleware',
 'django.middleware.clickjacking.XFrameOptionsMiddleware']


Traceback:

File "/home/utopia/pregweb/lib/python3.6/site-packages/django/db/backends/base/base.py" in _commit
  239.                 return self.connection.commit()

The above exception (FOREIGN KEY constraint failed) was the direct cause of the following exception:

Try to create a transaction like (signal part):尝试创建一个事务,如(信号部分):

transaction = Transaction(transfer_id=transfer.id,amount=transfer.amount)

I have added id to transfer.我已添加id以进行转移。

There are at least two problems here.这里至少有两个问题。

First, if you create a few DB entities at once, you need to wrap this block in a transaction.atomic .首先,如果您一次创建几个数据库实体,则需要将此块包装在transaction.atomic中。

Second, this model.二、这个model。

class Transaction(models.Model):
    id=models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    amount = models.IntegerField(editable=False)
    payment_id = models.ForeignKey(Payment,blank=True, on_delete=models.CASCADE, null=True)
    transfer_id = models.ForeignKey(Transfer, blank=True,null=True, on_delete=models.CASCADE)

Has nullable fk to Payment and Transfer .PaymentTransfer具有可为空的 fk。

That's how you create it这就是你创建它的方式

transfer = Transfer(
        transferred_to=instance, transferred_from=instance,transfer_reason='Initial Transfer',amount=0
    )
    transfer.save()

So you either need to add default=None on these fields and run migrations or pass None on creation.因此,您要么需要在这些字段上添加default=None并运行迁移,要么在创建时传递None

Third, don't add entity_id in your model.第三,不要在 model 中添加entity_id If you create如果你创建

 transfer = models.ForeignKey(Transfer...

Django will automatically add transfer_id on your model and that's what will be in the DB. Django 将自动在您的 model 上添加transfer_id ,这就是数据库中的内容。

docs 文档

Behind the scenes, Django appends "_id" to the field name to create its database column name.在幕后,Django 将“_id”附加到字段名称以创建其数据库列名称。 In the above example, the database table for the Car model will have a manufacturer_id column.在上面的示例中,Car model 的数据库表将有一个manufacturer_id 列。 (You can change this explicitly by specifying db_column) However, your code should never have to deal with the database column name, unless you write custom SQL. (您可以通过指定 db_column 显式更改此设置)但是,您的代码永远不必处理数据库列名,除非您编写自定义 SQL。 You'll always deal with the field names of your model object.您将始终处理 model object 的字段名称。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 django.db.utils.IntegrityError: FOREIGN KEY 约束失败 - django.db.utils.IntegrityError: FOREIGN KEY constraint failed django.db.utils.IntegrityError: FOREIGN KEY 约束在通过 Selenium 和 Python Django 执行 LiveServerTestCases 时失败 - django.db.utils.IntegrityError: FOREIGN KEY constraint failed while executing LiveServerTestCases through Selenium and Python Django Django错误django.db.utils.IntegrityError:FOREIGN KEY约束失败 - Django Error django.db.utils.IntegrityError: FOREIGN KEY constraint failed Createsuperuser django.db.utils.IntegrityError: NOT NULL 约束失败 - Createsuperuser django.db.utils.IntegrityError: NOT NULL constraint failed django.db.utils.IntegrityError:NOT NULL约束失败 - django.db.utils.IntegrityError: NOT NULL constraint failed django.db.utils.IntegrityError: NOT NULL 约束失败: - django.db.utils.IntegrityError: NOT NULL constraint failed: django.db.utils.IntegrityError: NOT NULL 约束失败来自 Postman - django.db.utils.IntegrityError: NOT NULL constraint failed fom Postman django.db.utils.IntegrityError:插入或更新表“authtoken_token”违反外键约束 - django.db.utils.IntegrityError: insert or update on table “authtoken_token” violates foreign key constraint django.db.utils.IntegrityError: NOT NULL 约束失败:app_users.key_value_id - django.db.utils.IntegrityError: NOT NULL constraint failed: app_users.key_value_id django.db.utils.IntegrityError: - django.db.utils.IntegrityError:
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM