Python 非空约束失败:课程\u课程所有者\u id

Python 非空约束失败:课程\u课程所有者\u id,python,django,django-2.0,Python,Django,Django 2.0,我正在创建一所学校,有点像,每当我试图通过URL创建课程时,notnull约束失败:courses\u course.owner\u idhttp://127.0.0.1:8000/course/create/。这是我的档案: models.py from django.db import models from django.contrib.auth.models import User from django.contrib.contenttypes.models import Conten

我正在创建一所学校,有点像,每当我试图通过URL创建课程时,
notnull约束失败:courses\u course.owner\u id
http://127.0.0.1:8000/course/create/。这是我的档案:

models.py

from django.db import models
from django.contrib.auth.models import User
from django.contrib.contenttypes.models import ContentType
from django.contrib.contenttypes.fields import GenericForeignKey
from .fields import OrderField


class Subject(models.Model):
    title = models.CharField(max_length=200)
    slug = models.SlugField(max_length=200, unique=True)

    class Meta:
        ordering = ('title',)

    def __str__(self):
        return self.title


class Course(models.Model):
    owner = models.ForeignKey(User, on_delete=models.CASCADE, related_name='courses_created')
    subject = models.ForeignKey(Subject, on_delete=models.CASCADE, related_name='courses')
    title = models.CharField(max_length=200)
    slug = models.SlugField(max_length=200, unique=True)
    overview = models.TextField()
    created = models.DateTimeField(auto_now_add=True)

    class Meta:
        ordering = ('-created',)

    def __str__(self):
        return self.title


class Module(models.Model):
    course = models.ForeignKey(Course, on_delete=models.CASCADE, related_name='modules')
    title = models.CharField(max_length=200)
    description = models.TextField(blank=True)
    order = OrderField(blank=True, for_fields=['course'])

    class Meta:
        ordering = ['order']

    def __str__(self):
        return '{}. {}'.format(self.order, self.title)


class Content(models.Model):
    module = models.ForeignKey(Module, on_delete=models.CASCADE, related_name='contents')
    content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE, limit_choices_to={
        'model__in':('text', 'video', 'image', 'file')
    })
    object_id = models.PositiveIntegerField()
    item = GenericForeignKey('content_type', 'object_id')
    order = OrderField(blank=True, for_fields=['module'])

    class Meta:
        ordering = ['order']


class ItemBase(models.Model):
    owner = models.ForeignKey(User, on_delete=models.CASCADE, related_name='%(class)s_related')
    title = models.CharField(max_length=200)
    created = models.DateTimeField(auto_now_add=True)
    updated = models.DateTimeField(auto_now=True)

    class Meta:
        abstract = True

    def __str__(self):
        return self.title


class Text(ItemBase):
    content = models.TextField()


class File(ItemBase):
    file = models.FileField(upload_to='files')


class Image(ItemBase):
    file = models.FileField(upload_to='images')


class Video(ItemBase):
    url = models.URLField()
url.py(在课程应用程序中)

'views.py'

from django.shortcuts import render
from django.urls import reverse_lazy
from django.views.generic.list import ListView
from django.views.generic.edit import CreateView, UpdateView, DeleteView
from django.contrib.auth.mixins import LoginRequiredMixin, PermissionRequiredMixin
from .models import Subject, Course

def home(request):
    subjects = Subjects.objects.all()
    return render(request, 'home.html', {'subjects' : subjects})

class OwnerMixin(object):
    def get_queryset(self):
        qs = super(OwnerMixin, self).get_queryset()
        return qs.filter(owner=self.request.user)

class OwnerEditMixin(object):
    def form_valid(self, form):
        form.instance.owner = self.request.user
        return super(OwnerEditMixin, self).form_valid(form)

class OwnerCourseMixin(OwnerMixin, LoginRequiredMixin):
    model = Course
    fields = ['subject', 'title', 'slug', 'overview']
    success_url = reverse_lazy('manage_course_list')

class OwnerCourseEditMixin(OwnerCourseMixin, OwnerEditMixin):
    fields = ['subject', 'title', 'slug', 'overview']
    success_url = reverse_lazy('manage_course_list')
    template_name = 'courses/manage/course/form.html'

class ManageCourseListView(OwnerCourseMixin, ListView):
    template_name = 'courses/manage/course/list.html'

class CourseCreateView(OwnerCourseEditMixin, CreateView, PermissionRequiredMixin):
    template_name = 'courses/manage/course/form.html'
    permission_required = 'courses.can_add'

class CourseUpdateView(OwnerCourseEditMixin, UpdateView, PermissionRequiredMixin):
    template_name = 'courses/manage/course/form.html'
    permission_required = 'courses.can_change'

class CourseDeleteView(OwnerCourseMixin, DeleteView, PermissionRequiredMixin):
    template_name = 'courses/manage/course/delete.html'
    success_url = reverse_lazy('manage_course_list')
    permission_required = 'courses.can_delete'
以及从终端的回溯:

Internal Server Error: /course/create/
Traceback (most recent call last):
  File "/home/caspian/Documents/Programming/Websites/school/schenv/lib/python3.6/site-packages/django/db/backends/utils.py", line 85, in _execute
    return self.cursor.execute(sql, params)
  File "/home/caspian/Documents/Programming/Websites/school/schenv/lib/python3.6/site-packages/django/db/backends/sqlite3/base.py", line 303, in execute
    return Database.Cursor.execute(self, query, params)
sqlite3.IntegrityError: NOT NULL constraint failed: courses_course.owner_id

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/home/caspian/Documents/Programming/Websites/school/schenv/lib/python3.6/site-packages/django/core/handlers/exception.py", line 35, in inner
    response = get_response(request)
  File "/home/caspian/Documents/Programming/Websites/school/schenv/lib/python3.6/site-packages/django/core/handlers/base.py", line 128, in _get_response
    response = self.process_exception_by_middleware(e, request)
  File "/home/caspian/Documents/Programming/Websites/school/schenv/lib/python3.6/site-packages/django/core/handlers/base.py", line 126, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "/home/caspian/Documents/Programming/Websites/school/schenv/lib/python3.6/site-packages/django/views/generic/base.py", line 69, in view
    return self.dispatch(request, *args, **kwargs)
  File "/home/caspian/Documents/Programming/Websites/school/schenv/lib/python3.6/site-packages/django/contrib/auth/mixins.py", line 52, in dispatch
    return super().dispatch(request, *args, **kwargs)
  File "/home/caspian/Documents/Programming/Websites/school/schenv/lib/python3.6/site-packages/django/views/generic/base.py", line 89, in dispatch
    return handler(request, *args, **kwargs)
  File "/home/caspian/Documents/Programming/Websites/school/schenv/lib/python3.6/site-packages/django/views/generic/edit.py", line 172, in post
    return super().post(request, *args, **kwargs)
  File "/home/caspian/Documents/Programming/Websites/school/schenv/lib/python3.6/site-packages/django/views/generic/edit.py", line 142, in post
    return self.form_valid(form)
  File "/home/caspian/Documents/Programming/Websites/school/schenv/lib/python3.6/site-packages/django/views/generic/edit.py", line 125, in form_valid
    self.object = form.save()
  File "/home/caspian/Documents/Programming/Websites/school/schenv/lib/python3.6/site-packages/django/forms/models.py", line 456, in save
    self.instance.save()
  File "/home/caspian/Documents/Programming/Websites/school/schenv/lib/python3.6/site-packages/django/db/models/base.py", line 729, in save
    force_update=force_update, update_fields=update_fields)
  File "/home/caspian/Documents/Programming/Websites/school/schenv/lib/python3.6/site-packages/django/db/models/base.py", line 759, in save_base
    updated = self._save_table(raw, cls, force_insert, force_update, using, update_fields)
  File "/home/caspian/Documents/Programming/Websites/school/schenv/lib/python3.6/site-packages/django/db/models/base.py", line 842, in _save_table
    result = self._do_insert(cls._base_manager, using, fields, update_pk, raw)
  File "/home/caspian/Documents/Programming/Websites/school/schenv/lib/python3.6/site-packages/django/db/models/base.py", line 880, in _do_insert
    using=using, raw=raw)
  File "/home/caspian/Documents/Programming/Websites/school/schenv/lib/python3.6/site-packages/django/db/models/manager.py", line 82, in manager_method
    return getattr(self.get_queryset(), name)(*args, **kwargs)
  File "/home/caspian/Documents/Programming/Websites/school/schenv/lib/python3.6/site-packages/django/db/models/query.py", line 1125, in _insert
    return query.get_compiler(using=using).execute_sql(return_id)
  File "/home/caspian/Documents/Programming/Websites/school/schenv/lib/python3.6/site-packages/django/db/models/sql/compiler.py", line 1280, in execute_sql
    cursor.execute(sql, params)
  File "/home/caspian/Documents/Programming/Websites/school/schenv/lib/python3.6/site-packages/django/db/backends/utils.py", line 100, in execute
    return super().execute(sql, params)
  File "/home/caspian/Documents/Programming/Websites/school/schenv/lib/python3.6/site-packages/django/db/backends/utils.py", line 68, in execute
    return self._execute_with_wrappers(sql, params, many=False, executor=self._execute)
  File "/home/caspian/Documents/Programming/Websites/school/schenv/lib/python3.6/site-packages/django/db/backends/utils.py", line 77, in _execute_with_wrappers
    return executor(sql, params, many, context)
  File "/home/caspian/Documents/Programming/Websites/school/schenv/lib/python3.6/site-packages/django/db/backends/utils.py", line 85, in _execute
    return self.cursor.execute(sql, params)
  File "/home/caspian/Documents/Programming/Websites/school/schenv/lib/python3.6/site-packages/django/db/utils.py", line 89, in __exit__
    raise dj_exc_value.with_traceback(traceback) from exc_value
  File "/home/caspian/Documents/Programming/Websites/school/schenv/lib/python3.6/site-packages/django/db/backends/utils.py", line 85, in _execute
    return self.cursor.execute(sql, params)
  File "/home/caspian/Documents/Programming/Websites/school/schenv/lib/python3.6/site-packages/django/db/backends/sqlite3/base.py", line 303, in execute
    return Database.Cursor.execute(self, query, params)
django.db.utils.IntegrityError: NOT NULL constraint failed: courses_course.owner_id
[02/Feb/2018 14:15:29] "POST /course/create/ HTTP/1.1" 500 180238

我已经尝试重新创建我的数据库,但它仍然不起作用

如果您尝试打印CourseCreateView的MRO,您将看到以下内容:

(<class 'test.CourseCreateView'>, <class 'test.OwnerCourseEditMixin'>, <class 'test.OwnerCourseMixin'>, <class 'test.OwnerMixin'>, <class 'django.contrib.auth.mixins.LoginRequiredMixin'>, <class 'django.views.generic.edit.CreateView'>, <class 'django.views.generic.detail.SingleObjectTemplateResponseMixin'>, <class 'django.views.generic.base.TemplateResponseMixin'>, <class 'django.views.generic.edit.BaseCreateView'>, <class 'django.views.generic.edit.ModelFormMixin'>, <class 'django.views.generic.edit.FormMixin'>, <class 'django.views.generic.detail.SingleObjectMixin'>, <class 'django.views.generic.base.ContextMixin'>, <class 'django.views.generic.edit.ProcessFormView'>, <class 'django.views.generic.base.View'>, <class 'django.contrib.auth.mixins.PermissionRequiredMixin'>, <class 'django.contrib.auth.mixins.AccessMixin'>, <class 'test.OwnerEditMixin'>, <class 'object'>)
并将
OwnerEditMixin
添加到
CreateView
之前视图的父视图中:

class CourseCreateView(OwnerCourseEditMixin, OwnerEditMixin, CreateView, PermissionRequiredMixin):
    template_name = 'courses/manage/course/form.html'
    permission_required = 'courses.can_add'

如果您尝试打印CourseCreateView的MRO,您将看到:

(<class 'test.CourseCreateView'>, <class 'test.OwnerCourseEditMixin'>, <class 'test.OwnerCourseMixin'>, <class 'test.OwnerMixin'>, <class 'django.contrib.auth.mixins.LoginRequiredMixin'>, <class 'django.views.generic.edit.CreateView'>, <class 'django.views.generic.detail.SingleObjectTemplateResponseMixin'>, <class 'django.views.generic.base.TemplateResponseMixin'>, <class 'django.views.generic.edit.BaseCreateView'>, <class 'django.views.generic.edit.ModelFormMixin'>, <class 'django.views.generic.edit.FormMixin'>, <class 'django.views.generic.detail.SingleObjectMixin'>, <class 'django.views.generic.base.ContextMixin'>, <class 'django.views.generic.edit.ProcessFormView'>, <class 'django.views.generic.base.View'>, <class 'django.contrib.auth.mixins.PermissionRequiredMixin'>, <class 'django.contrib.auth.mixins.AccessMixin'>, <class 'test.OwnerEditMixin'>, <class 'object'>)
并将
OwnerEditMixin
添加到
CreateView
之前视图的父视图中:

class CourseCreateView(OwnerCourseEditMixin, OwnerEditMixin, CreateView, PermissionRequiredMixin):
    template_name = 'courses/manage/course/form.html'
    permission_required = 'courses.can_add'

甚至还有一个更简单的解决方案,只需在开始时移动
PermissionRequiredMixin
。仔细看看你书中的例子,因为我假设你使用的是和我一样的-总是第一个。

甚至还有一个更简单的解决方案,只需在开始时移动
PermissionRequiredMixin
。仔细看一下你书中的例子,因为我假设你使用的和我一样——总是第一个

class CourseCreateView(OwnerCourseEditMixin, OwnerEditMixin, CreateView, PermissionRequiredMixin):
    template_name = 'courses/manage/course/form.html'
    permission_required = 'courses.can_add'