2016-12-20 20 views
0

我延長了用戶模式,包括用下面的代碼的輪廓:擴展用戶的個人資料,包括輪廓模型後,Django會拋出唯一約束失敗錯誤

class Profile(models.Model): 
    PTO_TIER_CHOICES = (
     (200.0, 'Boss 5-10 Years'), 
     (160.0, 'Boss 2-5 Years'), 
     (120.0, 'Boss 0-2 Years'), 
     (160.0, 'Peon 5-10 Years'), 
     (120.0, 'Peon 2-5 Years'), 
     (90.0, 'Peon 0-2 Years'), 
    ) 

    user = models.OneToOneField(User, on_delete=models.CASCADE) 
    pto_tier = models.FloatField(choices=PTO_TIER_CHOICES, default=90.0) 

    def __str__(self): 
     return self.user.username 

@receiver(post_save, sender=User) 
def create_user_profile(sender, instance, created, **kwargs): 
    if created: 
     Profile.objects.create(user=instance) 

@receiver(post_save, sender=User) 
def save_user_profile(sender, instance, **kwargs): 
    instance.profile.save() 

我還創建了一個LeaveHistory模型的外鍵用下面的代碼在用戶模式:

class LeaveHistory(models.Model): 
    LEAVE_CHOICES = (
     (True, 'PTO'), #is chargeable? 
     (False, 'Jury Duty'), #is chargeable? 
     (False, 'Voting'), #is chargeable? 
     (False, 'Military Leave'), #is chargeable? 
     (False, 'Bereavement'), #is chargeable? 
     (True, 'Emergency'), #is chargeable? 
    ) 

    user = models.ForeignKey(User, on_delete=models.CASCADE) 
    leave_start_date = models.DateTimeField(auto_now=False, auto_now_add=False) 
    leave_end_date = models.DateTimeField(auto_now=False, auto_now_add=False) 
    leave_type = models.BooleanField(choices=LEAVE_CHOICES) 

    def __str__(self): 
     return self.user.username 

,我遇到的問題是,每當我嘗試使用相同的用戶名,我得到以下錯誤創建多個LeaveHistories:

IntegrityError at /admin/accounts/leavehistory/add/ 
UNIQUE constraint failed: accounts_leavehistory.user_id 
Request Method: POST 
Request URL: http://localhost:8000/admin/accounts/leavehistory/add/ 
Django Version: 1.10.3 
Exception Type: IntegrityError 
Exception Value:  
UNIQUE constraint failed: accounts_leavehistory.user_id 
Exception Location: C:\Users\achesley\AppData\Local\Programs\Python\Python35-32\lib\site-packages\django\db\backends\sqlite3\base.py in execute, line 337 
Python Executable: C:\Users\achesley\AppData\Local\Programs\Python\Python35-32\python.exe 
Python Version: 3.5.2 
Python Path:  
['C:\\django projects\\company_projects', 
'C:\\Users\\achesley\\AppData\\Local\\Programs\\Python\\Python35-32\\python35.zip', 
'C:\\Users\\achesley\\AppData\\Local\\Programs\\Python\\Python35-32\\DLLs', 
'C:\\Users\\achesley\\AppData\\Local\\Programs\\Python\\Python35-32\\lib', 
'C:\\Users\\achesley\\AppData\\Local\\Programs\\Python\\Python35-32', 
'C:\\Users\\achesley\\AppData\\Local\\Programs\\Python\\Python35-32\\lib\\site-packages'] 
Server time: Tue, 20 Dec 2016 16:03:13 -0700 

Environment: 


Request Method: POST 
Request URL: http://localhost:8000/admin/accounts/leavehistory/add/ 

Django Version: 1.10.3 
Python Version: 3.5.2 
Installed Applications: 
['django.contrib.admin', 
'django.contrib.auth', 
'django.contrib.contenttypes', 
'django.contrib.sessions', 
'django.contrib.messages', 
'django.contrib.staticfiles', 
'crispy_forms', 
'accounts'] 
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 "C:\Users\achesley\AppData\Local\Programs\Python\Python35-32\lib\site-packages\django\db\backends\utils.py" in execute 
    64.     return self.cursor.execute(sql, params) 

File "C:\Users\achesley\AppData\Local\Programs\Python\Python35-32\lib\site-packages\django\db\backends\sqlite3\base.py" in execute 
    337.   return Database.Cursor.execute(self, query, params) 

The above exception (UNIQUE constraint failed: accounts_leavehistory.user_id) was the direct cause of the following exception: 

File "C:\Users\achesley\AppData\Local\Programs\Python\Python35-32\lib\site-packages\django\core\handlers\exception.py" in inner 
    39.    response = get_response(request) 

File "C:\Users\achesley\AppData\Local\Programs\Python\Python35-32\lib\site-packages\django\core\handlers\base.py" in _get_response 
    187.     response = self.process_exception_by_middleware(e, request) 

File "C:\Users\achesley\AppData\Local\Programs\Python\Python35-32\lib\site-packages\django\core\handlers\base.py" in _get_response 
    185.     response = wrapped_callback(request, *callback_args, **callback_kwargs) 

File "C:\Users\achesley\AppData\Local\Programs\Python\Python35-32\lib\site-packages\django\contrib\admin\options.py" in wrapper 
    544.     return self.admin_site.admin_view(view)(*args, **kwargs) 

File "C:\Users\achesley\AppData\Local\Programs\Python\Python35-32\lib\site-packages\django\utils\decorators.py" in _wrapped_view 
    149.      response = view_func(request, *args, **kwargs) 

File "C:\Users\achesley\AppData\Local\Programs\Python\Python35-32\lib\site-packages\django\views\decorators\cache.py" in _wrapped_view_func 
    57.   response = view_func(request, *args, **kwargs) 

File "C:\Users\achesley\AppData\Local\Programs\Python\Python35-32\lib\site-packages\django\contrib\admin\sites.py" in inner 
    211.    return view(request, *args, **kwargs) 

File "C:\Users\achesley\AppData\Local\Programs\Python\Python35-32\lib\site-packages\django\contrib\admin\options.py" in add_view 
    1509.   return self.changeform_view(request, None, form_url, extra_context) 

File "C:\Users\achesley\AppData\Local\Programs\Python\Python35-32\lib\site-packages\django\utils\decorators.py" in _wrapper 
    67.    return bound_func(*args, **kwargs) 

File "C:\Users\achesley\AppData\Local\Programs\Python\Python35-32\lib\site-packages\django\utils\decorators.py" in _wrapped_view 
    149.      response = view_func(request, *args, **kwargs) 

File "C:\Users\achesley\AppData\Local\Programs\Python\Python35-32\lib\site-packages\django\utils\decorators.py" in bound_func 
    63.     return func.__get__(self, type(self))(*args2, **kwargs2) 

File "C:\Users\achesley\AppData\Local\Programs\Python\Python35-32\lib\contextlib.py" in inner 
    30.     return func(*args, **kwds) 

File "C:\Users\achesley\AppData\Local\Programs\Python\Python35-32\lib\site-packages\django\contrib\admin\options.py" in changeform_view 
    1449.     self.save_model(request, new_object, form, not add) 

File "C:\Users\achesley\AppData\Local\Programs\Python\Python35-32\lib\site-packages\django\contrib\admin\options.py" in save_model 
    1007.   obj.save() 

File "C:\Users\achesley\AppData\Local\Programs\Python\Python35-32\lib\site-packages\django\db\models\base.py" in save 
    796.      force_update=force_update, update_fields=update_fields) 

File "C:\Users\achesley\AppData\Local\Programs\Python\Python35-32\lib\site-packages\django\db\models\base.py" in save_base 
    824.    updated = self._save_table(raw, cls, force_insert, force_update, using, update_fields) 

File "C:\Users\achesley\AppData\Local\Programs\Python\Python35-32\lib\site-packages\django\db\models\base.py" in _save_table 
    908.    result = self._do_insert(cls._base_manager, using, fields, update_pk, raw) 

File "C:\Users\achesley\AppData\Local\Programs\Python\Python35-32\lib\site-packages\django\db\models\base.py" in _do_insert 
    947.        using=using, raw=raw) 

File "C:\Users\achesley\AppData\Local\Programs\Python\Python35-32\lib\site-packages\django\db\models\manager.py" in manager_method 
    85.     return getattr(self.get_queryset(), name)(*args, **kwargs) 

File "C:\Users\achesley\AppData\Local\Programs\Python\Python35-32\lib\site-packages\django\db\models\query.py" in _insert 
    1045.   return query.get_compiler(using=using).execute_sql(return_id) 

File "C:\Users\achesley\AppData\Local\Programs\Python\Python35-32\lib\site-packages\django\db\models\sql\compiler.py" in execute_sql 
    1054.     cursor.execute(sql, params) 

File "C:\Users\achesley\AppData\Local\Programs\Python\Python35-32\lib\site-packages\django\db\backends\utils.py" in execute 
    79.    return super(CursorDebugWrapper, self).execute(sql, params) 

File "C:\Users\achesley\AppData\Local\Programs\Python\Python35-32\lib\site-packages\django\db\backends\utils.py" in execute 
    64.     return self.cursor.execute(sql, params) 

File "C:\Users\achesley\AppData\Local\Programs\Python\Python35-32\lib\site-packages\django\db\utils.py" in __exit__ 
    94.     six.reraise(dj_exc_type, dj_exc_value, traceback) 

File "C:\Users\achesley\AppData\Local\Programs\Python\Python35-32\lib\site-packages\django\utils\six.py" in reraise 
    685.    raise value.with_traceback(tb) 

File "C:\Users\achesley\AppData\Local\Programs\Python\Python35-32\lib\site-packages\django\db\backends\utils.py" in execute 
    64.     return self.cursor.execute(sql, params) 

File "C:\Users\achesley\AppData\Local\Programs\Python\Python35-32\lib\site-packages\django\db\backends\sqlite3\base.py" in execute 
    337.   return Database.Cursor.execute(self, query, params) 

Exception Type: IntegrityError at /admin/accounts/leavehistory/add/ 
Exception Value: UNIQUE constraint failed: accounts_leavehistory.user_id 

我知道它可能與擴展用戶模型有關,因爲我在另一個項目上嘗試過,用戶模型沒有被擴展並且工作正常。如果你需要其他的代碼片段或澄清讓我知道,謝謝。

+0

你運行'makemigrations'和'migrate'嗎? – Selcuk

+1

錯誤與您的模型不一致。如果您需要幫助,請發佈確切的錯誤痕跡跟蹤 – e4c5

+0

@selcuk我運行了makemigrations並遷移,但沒有解決問題。然後我刷新數據庫並從頭開始,它仍然不起作用。 – FlashBanistan

回答

0

我改變了LeaveHistory模型從:

user = models.OneToOneField(User, on_delete=models.CASCADE) 

到:

user = models.ForeignKey(User, on_delete=models.CASCADE) 

,但我並沒有採用正確的遷移這就造成了我的唯一約束錯誤。 我不停地跑

蟒蛇manage.py makemigrations

這不發現我應用任何新的變化。爲我工作的正確方法是在makemigrations命令來指定應用程序的名稱,

蟒蛇manage.py makemigrations [應用程序名稱]

它檢測到的變化,然後我可以運行蟒蛇管理.py遷移併成功將更改應用到我的數據庫。

-2

這是因爲您通過外鍵將LeaveHistory鏈接到用戶模型。相反,你應該鏈接到Profile模型。

class LeaveHistory(models.Model): 
    ... 
    profile = models.ForeignKey(Profile, on_delete=models.CASCADE) 
+0

那麼這將如何解決問題?無論如何,'Profile'和'User'通過OneToOne關係相互關聯。 – Selcuk

+0

用戶意圖以抽象的方式使用,以便它不與特定於應用程序的事物相關聯。這就是爲什麼你創建一個Profile模型,以便它可以用作'中間人'。 用戶模型在Django身份驗證系統中是默認的,我相信它是受限制的,所以外鍵在相關表中必須是唯一的。所以在你的情況下,你只能有一個用戶引用到一個LeaveHistory實例,並且不能用同一個用戶創建另一個用戶。 我不認爲你會遇到與配置文件的這個問題。 – zubhav

+1

這是純粹的推測,與問題中的問題無關。 'User'不是一個抽象模型,並且沒有什麼神奇的方法可以將另一個模型中的外鍵**約束爲唯一的,除非子模型被定義爲這樣。 OP可能將'user' fk定義爲唯一的,或者是1對1的字段,但卻忘記遷移數據庫模式。 – Selcuk