IntegrityError:book\u app\u author.book\u id不能为空

2024-10-02 18:26:21 发布

您现在位置:Python中文网/ 问答频道 /正文

所以,这个问题被问了很多次,但是我很难将这些解决方案应用到我的应用程序中

型号:

    class User(models.Model):
    name = models.CharField(max_length=45)
    alias = models.CharField(max_length=45)
    email = models.EmailField()
    password = models.CharField(max_length=45)
    objects = UserManager()
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)
    def __str__(self):
        return self.name

class Author(models.Model):
    name = models.CharField(max_length=45)
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)
    def __str__(self):
        return self.name

class Book(models.Model):
    title = models.CharField(max_length=45)
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)    
    author = models.ForeignKey(Author)
    user = models.ManyToManyField(User, related_name='books')
    def __str__(self):
        return self.title

class Review(models.Model):
    content = models.TextField()
    rating = models.IntegerField()
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)
    user = models.ManyToManyField(User, related_name='reviews')
    book = models.ManyToManyField(Book, related_name='reviews'

视图时,除非尝试创建新作者,否则错误会在第一个视图中弹出

def add_book(request):

    if request.method == 'POST':
        user = User.objects.get(pk=request.session['user_id'])

        data = {
            'title':request.POST['title'],
            'content':request.POST['review'],
            'rating':request.POST['rating'],
        }

        #Create new author or add author 
        author_name = request.POST['new_author']
        print 'About to see if a new author was provided'
        if len(author_name) > 0:
            try:
                print ' Trying to get existin author '
                author = Author.objects.get(name=author_name)
            except:
                print 'Trying to create a new author'
                Author.objects.create(name=author_name)
        else:            
            print 'About to set author to existing author '
            author_name = request.POST['author']
            author = Author.objects.get(name=author_name)
        print 'Author is ', author

        #Create book entry
        try:
            book = Book.objects.get(name=data['title'])
        except:
            book = Book.objects.create(name=data['title'], author=author, user=user)
            print 'New book added'



    return redirect('/books')

错误:

IntegrityError at /add_book
book_app_author.book_id may not be NULL
Request Method: POST
Request URL:    http://127.0.0.1:8000/add_book
Django Version: 1.11.1
Exception Type: IntegrityError
Exception Value:    
book_app_author.book_id may not be NULL
Exception Location: C:\Users\kamar\Desktop\DojoAssignments\django\djangoEnv\djangoEnv\lib\site-packages\django\db\backends\sqlite3\base.py in execute, line 328
Python Executable:  C:\Users\kamar\Desktop\DojoAssignments\django\djangoEnv\djangoEnv\Scripts\python.exe
Python Version: 2.7.10
Python Path:    
['C:\\Users\\kamar\\Desktop\\DojoAssignments\\django\\new_belt',
 'C:\\windows\\SYSTEM32\\python27.zip',
 'C:\\Users\\kamar\\Desktop\\DojoAssignments\\django\\djangoEnv\\djangoEnv\\DLLs',
 'C:\\Users\\kamar\\Desktop\\DojoAssignments\\django\\djangoEnv\\djangoEnv\\lib',
 'C:\\Users\\kamar\\Desktop\\DojoAssignments\\django\\djangoEnv\\djangoEnv\\lib\\plat-win',
 'C:\\Users\\kamar\\Desktop\\DojoAssignments\\django\\djangoEnv\\djangoEnv\\lib\\lib-tk',
 'C:\\Users\\kamar\\Desktop\\DojoAssignments\\django\\djangoEnv\\djangoEnv\\Scripts',
 'C:\\Python27\\Lib',
 'C:\\Python27\\DLLs',
 'C:\\Python27\\Lib\\lib-tk',
 'C:\\Users\\kamar\\Desktop\\DojoAssignments\\django\\djangoEnv\\djangoEnv',
 'C:\\Users\\kamar\\Desktop\\DojoAssignments\\django\\djangoEnv\\djangoEnv\\lib\\site-packages']
Server time:    Mon, 29 May 2017 17:08:42 +0000

Tags: djangonameaddautomodelsusersnowat
3条回答

使用一个模型表单会使这个视图更加紧凑,但是在这种情况下,我会考虑对您的视图进行一些更改

像这样编辑视图

def add_book(request):
    if request.method == 'POST':
        user = request.user
        data = {
            'title':request.POST.get('title'),
            'content':request.POST.get('review'),
            'rating':request.POST.get('rating'),
        }
        author_name = request.POST.get('new_author')
        if author_name:
            author, created = Author.objects.get_or_create(name=author_name)
        else:            
            author_name = request.POST.get('author')
            author = Author.objects.get(name=author_name)
        try:
            book = Book.objects.get(title=data['title'])
        except:
            book = Book.objects.create(title=data['title'], author=author)
        book.user.add(user)
        book.save()
    return redirect('/books')

我已经测试了你的代码。我认为你有一个过时的sqlite数据库

请尝试以下内容

  • 删除sqlite数据库
  • 通过python manage.py makemigrations重新生成迁移
  • 通过python manage.py migrate更新数据库

代码的某些部分需要修复

首先,图书模型没有名称字段

所以,这条线需要修好

book = Book.objects.create(name=data['title'], author=author, user=user)

这将是

book = Book.objects.create(title=data['title'], author=author)

第二,不能像这样分配多对多字段user

book = Book.objects.create(name=data['title'], author=author, user=user)

正确的格式是

book = Book.objects.create(title=data['title'], author=author)

book.user.add(user)

为了方便你,我上传了一个固定版本的应用程序

https://github.com/ibrahim12/stackoverflow_question_solve

您真的应该使用两个模型表单来完成这一切,并使用内置的is\u valid and save()方法。那就很容易解决这个问题了

另外,要获取当前用户,只需使用request.user,而不是在数据库中查找它

将视图更改为模型表单后,可以使用this方法而不会出现任何问题

在您的评论之后: 试试这个:

       if len(author_name) > 0:
            try:
                print ' Trying to get existin author '
                author = Author.objects.get(name=author_name)
            except:
                print 'Trying to create a new author'
                author = Author.objects.create(name=author_name) # you did not set the author here
        else:            
            print 'About to set author to existing author '
            author_name = request.POST['author']
            author = Author.objects.get(name=author_name)

相关问题 更多 >