[英]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
.对
Payment
和Transfer
具有可为空的 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
,这就是数据库中的内容。
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.