IntegrityError:book_app_author.book_id可能不为NULL

时间:2017-05-29 17:13:46

标签: python django django-models

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

型号:

    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

3 个答案:

答案 0 :(得分:0)

您应该使用两个模型表单来完成所有这些操作,并使用内置的is_valid和save()方法。然后很容易理解这个问题。

此外,要让当前用户只使用request.user而不是在db中查找。

将视图更改为模型表单后,您可以毫无问题地使用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)

答案 1 :(得分:0)

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

像这样编辑你的观点,

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')

答案 2 :(得分:0)

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

请尝试以下,

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

代码的某些部分需要修复。

首先,Book模型没有名称字段。

所以,这条线需要修复。

  
    

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(用户)

  

为方便起见,我上传了该应用的固定版本。

this