在Django视图中向Postgres添加用户/帐户表

Chr*_*ris 5 python django postgresql django-views

前往编辑2

在views.py中调用以下adduser函数。我首先保存用户,因为它的ID(由Django在INSERT上自动创建)是帐户和密码的主键/外键。添加用户似乎工作正常,但是当到达时,会Accounts(user=u)引发以下错误:

IntegrityError at /adduser
insert or update on table "OmniCloud_App_accounts" violates foreign key constraint "user_id_refs_id_468fbcec324e93d2"
DETAIL:  Key (user_id)=(4) is not present in table "OmniCloud_App_user".
Run Code Online (Sandbox Code Playgroud)

但是密钥应该在那里,因为它只是将用户保存到数据库中。

def adduser(request):
    username = request.POST['username']
    password = request.POST['password']
    u = User.objects.create_user(username, request.POST['email'], password)
    u.save()
    a = Accounts(user=u)
    p = Passwords(user=u)
    a.save()
    p.save()
    user = authenticate(username=username, password=password)
    if user is not None and user.is_active:
        auth.login(request, user)
        return HttpResponseRedirect("/%s/" %u.id)
    else:
        return HttpResponseRedirect("/account/invalid/")
Run Code Online (Sandbox Code Playgroud)

编辑:这是帐户初始化的开始:

from django.db import models
from django.contrib.auth.models import User
class Accounts(models.Model):   
    user = models.ForeignKey(User)
Run Code Online (Sandbox Code Playgroud)

编辑2 我已经意识到,通过转到管理页面,当它抱怨数据库中没有4时,那是因为它正在添加第3个用户。添加第4位用户会引发错误,提示没有ID为5(duh)的用户。我在代码中看不到任何会导致它搜索user_id + 1的内容,

到战争宝箱!

Erw*_*ter 4

我的钱花在拼写错误的名字上。我在错误消息中注意到您有

OmniCloud_App_accounts
OmniCloud_App_user
Run Code Online (Sandbox Code Playgroud)

第二个表使用单数。不会偶然出现第二个这样的表:

OmniCloud_App_users
Run Code Online (Sandbox Code Playgroud)

此外,在 PostgreSQL 中使用混合大小写标识符在 SO 上也是一个很好的声誉来源。它迟早会咬你。这种愚蠢行为的受害者是这里的常客。任何具有此名称的表都可能 - 并且您忘记了某个地方的双引号"OmniCloud_App_user"

omnicloud_app_user
Run Code Online (Sandbox Code Playgroud)

要么是这样,要么是保存用户的事务尚未提交。您是否可以只创建用户(还没有帐户)并检查它是否最终位于表中的正确数据库中并具有正确的 ID?

编辑:诊断问题的工具

如果您知道正在创建用户,那么问题是:外键约束是否user_id_refs_id_468fbcec324e93d2位于正确的位置?同一个数据库?相同的架构?同一张桌子?

要找出数据库中存在哪些表,请尝试以下查询(如果您有必要的权限):

SELECT n.nspname AS schema_name
      ,c.relname AS table_name
      ,c.relhastriggers
      ,c.reltuples
FROM   pg_catalog.pg_class c
LEFT   JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace
WHERE  c.relname ~~* '%user%'
AND    c.relkind = 'r'
AND    nspname <> 'pg_catalog';
Run Code Online (Sandbox Code Playgroud)

显示名称中包含“user”的所有模式中的所有表,不区分大小写。另外,如果表有触发器(可能会导致您的问题)以及其中有多少行(估计由 更新ANALYZE)。可能会给你一个线索...

\d您还可以使用标准命令行客户端(交互式终端)的元命令psql

我将运行一个测试用例并让 postgres 服务器记录它得到的所有内容。为此目的设置此参数:

set log_statement = 'all';
Run Code Online (Sandbox Code Playgroud)

关于logging-parameters的手册。

log_statement(枚举)

控制记录哪些 SQL 语句。有效值为 none(关闭)、ddl、mod 和 all(所有语句)。

本手册介绍了如何设置参数