Django 抛出重复键值违反唯一约束错误
我在学习Django框架,里面有一个练习是让你创建一个简单的博客网页应用。这个应用有一些简单的模型和表单,用来处理理论用户在项目数据库中保存的数据。
以下是模型:
from django.db import models
class Blog(models.Model):
text = models.TextField()
date_added = models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.text
class Post(models.Model):
blog = models.ForeignKey(Blog, on_delete=models.CASCADE)
text = models.TextField()
date_added = models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.text
以下是表单:
from django import forms
from . models import Blog, Post
class BlogForm(forms.ModelForm):
class Meta:
model = Blog
fields = ['text']
labels = {'text': ''}
class PostForm(forms.ModelForm):
class Meta:
model = Post
fields = ['text']
labels = {'text': ''}
假设我通过数据库添加了一个博客实例。这样做:
INSERT INTO learning_logs_topic (id, text, date_added)
VALUES
(1, 'A blog #1', now()::timestamptz);
这些数据会出现在Django的管理网站和HTML模板上。几乎是瞬间就能看到,这意味着Django确实知道数据库里新增了数据。但是,当我试图通过管理网站或保存HTML表单来添加一个博客实例时,Django却报错了。
这里我尝试添加一个ID为21的博客实例:
INSERT INTO blogs_blog (id, text, date_added)
VALUES
(21, 'test21', now()::timestamptz);
结果我收到了这个错误:
在 /add_new_blog/ 出现了IntegrityError。
duplicate key value violates unique constraint "blogs_blog_pkey"
DETAIL: Key (id)=(21) already exists.
我不太明白这是怎么回事。Django从数据库中获取数据并发送到浏览器,但在尝试将数据写入数据库时,它却“看不见”这个ID。
我觉得我需要让Django能够识别数据库中的最新ID。
1 个回答
0
我不太明白这里发生了什么。Django从数据库中获取数据并发送到浏览器,但在尝试将数据写入数据库时,它似乎“看不见”ID。
Django其实并不生成ID,这个工作是数据库自己完成的。在使用PostgreSQL的情况下,通常是通过一个叫做序列 [pgsql-doc]来实现的。如果你手动添加一条记录并指定了id
(这通常是个非常糟糕的主意),那么序列就不会更新了。
这个回答展示了如何更新序列,这样从现在开始,它会从22
开始生成序列(在这个例子中)。
不过我建议在插入值的时候,不要一开始就指定主键。通常你应该把主键看作一个“黑箱值”。没错,这里是个整数,出于技术原因,但比如说,把两个主键加在一起是没有意义的,所以它只是一个实现细节。