我创建了一所学校,有点儿,每当我尝试通过网址NOT NULL constraint failed: courses_course.owner_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()
urls.py (in the courses app)
from django.urls import path
from . import views
urlpatterns = [
path('mine/', views.ManageCourseListView.as_view(),
name='manage_course_list'),
path('create/', views.CourseCreateView.as_view(),
name='course_create'),
path('<int:pk>/edit', views.CourseUpdateView.as_view(),
name='course_edit'),
path('<int:pk>/delete', views.CourseDeleteView.as_view(),
name='course_delete'),
]
urls.py (base)
from django.contrib import admin
from django.urls import include, path
from django.contrib.auth import views as auth_views
from courses import views
urlpatterns = [
path('', views.home, name='home'),
path('login/', auth_views.login, name='login'),
path('logout/', auth_views.logout, name='logout'),
path('admin/', admin.site.urls),
path('course/', include('courses.urls')),
]
&#39; views.py&#39;
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
我已经尝试重新创建我的数据库,但它仍无法正常工作
答案 0 :(得分:1)
如果您尝试打印CourseCreateView的MRO,您将看到:
sorted()
正如您所看到的sorted(zip(r, X])
((0, [1,2,3]), (1, [5,6,7]), (2, [2,4,5]))
位于通用zip
之后,因此您的自定义sorted
永远不会被调用。要解决此问题,您可以将([1,2,3], [5,6,7], [2,4,5])
和(<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
之前将form_valid
添加到View的父级:
OwnerCourseEditMixin
答案 1 :(得分:0)
还有一个更简单的解决方案,只需在开始时移动PermissionRequiredMixin
。仔细查看您书中的示例,因为我假设您使用的方法与我相同-始终在第一位。