[英]django.db.utils.IntegrityError: FOREIGN KEY constraint failed
[英]django.db.utils.IntegrityError: FOREIGN KEY constraint failed in django
在使用 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()
但是,在使用 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...
我嘗試通過在與用戶 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)
請注意 db_constraint=False 我在每個 model 上添加了一個 ForeignKey rxnship 給用戶 model。 注意:我使用我的用戶 model 作為自定義用戶 model,並使用 sqlite3 作為我的數據庫
這是 postman 中的測試
{
"name":"shifa",
"phone":"0705674532",
"pin_code":"2011",
"confirm_pin":"2011",
"expected_delivery_month":"December"
}
它是一個發布請求並返回以下錯誤。
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:
嘗試創建一個事務,如(信號部分):
transaction = Transaction(transfer_id=transfer.id,amount=transfer.amount)
我已添加id
以進行轉移。
這里至少有兩個問題。
首先,如果您一次創建幾個數據庫實體,則需要將此塊包裝在transaction.atomic
中。
二、這個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)
對Payment
和Transfer
具有可為空的 fk。
這就是你創建它的方式
transfer = Transfer(
transferred_to=instance, transferred_from=instance,transfer_reason='Initial Transfer',amount=0
)
transfer.save()
因此,您要么需要在這些字段上添加default=None
並運行遷移,要么在創建時傳遞None
。
第三,不要在 model 中添加entity_id
。 如果你創建
transfer = models.ForeignKey(Transfer...
Django 將自動在您的 model 上添加transfer_id
,這就是數據庫中的內容。
在幕后,Django 將“_id”附加到字段名稱以創建其數據庫列名稱。 在上面的示例中,Car model 的數據庫表將有一個manufacturer_id 列。 (您可以通過指定 db_column 顯式更改此設置)但是,您的代碼永遠不必處理數據庫列名,除非您編寫自定義 SQL。 您將始終處理 model object 的字段名稱。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.