在我得到显而易见的响应之前,关于检查数据库本身,我首先会说我已经检查了this post,它与我的设置几乎相同,以及删除的解决方案正如预期的那样,数据库和迁移以及在表中添加默认值都不起作用。但是,我确实希望解决方案非常简单。
那就是说,我正在做the tutorial for django-rest-framework而我的问题始于part 4。教程如下:
现在,如果再次打开浏览器并刷新页面,您会在页面右上方看到“登录”链接。如果您以之前创建的某个用户身份登录,则可以再次创建代码段。
创建一些代码段后,导航到'/ users /' 端点,并注意该表示包括一个列表 每个用户的每个用户关联的代码段pks 'snippets'字段。
因此,我尝试使用manage.py shell创建“snippets”对象,如本教程的第一部分所示,使用以下代码:
from snippets.models import Snippet
from snippets.serializers import SnippetSerializer
snippet = Snippet(code='foo = "bar"\n')
snippet.save()
这就是结束的地方。 .save()触发错误,我在下面打印了回溯。
使用之前回答的问题的建议,我稍微改变了我的设置,但我仍然收到错误。这是设置:
models.py:
from django.db import models
from pygments.lexers import get_all_lexers
from pygments.styles import get_all_styles
from pygments.lexers import get_lexer_by_name
from pygments.formatters.html import HtmlFormatter
from pygments import highlight
LEXERS = [item for item in get_all_lexers() if item[1]]
LANGUAGE_CHOICES = sorted([(item[1][0], item[0]) for item in LEXERS])
STYLE_CHOICES = sorted((item, item) for item in get_all_styles())
class Snippet(models.Model):
owner = models.ForeignKey('auth.User', related_name='snippets')
highlighted = models.TextField(default='')
created = models.DateTimeField(auto_now_add=True)
title = models.CharField(max_length=100, blank=True, default='')
code = models.TextField()
linenos = models.BooleanField(default=False)
language = models.CharField(choices=LANGUAGE_CHOICES, default='python', max_length=100)
style = models.CharField(choices=STYLE_CHOICES, default='friendly',max_length=100 )
class Meta:
ordering = ('created',)
def save(self, *args, **kwargs):
lexer = get_lexer_by_name(self.language)
linenos = self.linenos and 'table' or False
options = self.title and {'title': self.title} or {}
formatter = HtmlFormatter(style=self.style, linenos=linenos,
full=True, **options)
self.highlighted = highlight(self.code, lexer, formatter)
super(Snippet, self).save(*args, **kwargs)
serializers.py:
from rest_framework import serializers
from snippets.models import Snippet, LANGUAGE_CHOICES,STYLE_CHOICES
from django.contrib.auth.models import User
class SnippetSerializer(serializers.ModelSerializer):
owner = serializers.ReadOnlyField(source='owner.username')
class Meta:
model = Snippet
fields = ('id', 'title', 'code', 'linenos', 'language', 'style', 'owner')
class UserSerializer(serializers.ModelSerializer):
snippets = serializers.PrimaryKeyRelatedField(many=True, queryset=Snippet.objects.all())
class Meta:
model = User
fields = ('id', 'username', 'snippets')
views.py:
from snippets.models import Snippet
from snippets.serializers import SnippetSerializer, UserSerializer
from rest_framework import generics
from django.contrib.auth.models import User
from rest_framework import permissions
class SnippetList(generics.ListCreateAPIView):
queryset = Snippet.objects.all()
serializer_class = SnippetSerializer
permission_classes = (permissions.IsAuthenticatedOrReadOnly,)
def perform_create(self, serializer):
serializer.save(owner=self.request.user)
class SnippetDetail(generics.RetrieveUpdateDestroyAPIView):
queryset = Snippet.objects.all()
serializer_class = SnippetSerializer
permission_classes = (permissions.IsAuthenticatedOrReadOnly,)
class UserList(generics.ListAPIView):
queryset = User.objects.all()
serializer_class = UserSerializer
class UserDetail(generics.RetrieveAPIView):
queryset = User.objects.all()
serializer_class = UserSerializer
/snippets/urls.py
from django.conf.urls import url, include
from snippets.views import SnippetList, SnippetDetail, UserList, UserDetail
from rest_framework.urlpatterns import format_suffix_patterns
urlpatterns = [
url(r'^snippets/$', SnippetList.as_view()),
url(r'^snippets/(?P<pk>[0-9]+)/$', SnippetDetail.as_view()),
url(r'^users/$', UserList.as_view()),
url(r'^users/(?P<pk>[0-9]+)/$', UserDetail.as_view()),
]
urlpatterns = format_suffix_patterns(urlpatterns)
urlpatterns += [
url(r'^api-auth/', include('rest_framework.urls',
namespace='rest_framework')),
]
urls.py:
from django.conf.urls import url, include
urlpatterns = [
url(r'^', include('snippets.urls')),
]
,最后,丑陋的追溯:
In [6]: snippet.save()
---------------------------------------------------------------------------
OperationalError Traceback (most recent call last)
C:\Users\Jordon\AppData\Local\Programs\Python\Python35\lib\site-packages\django\db\backends\utils.py in execute(self, sql, params)
63 else:
---> 64 return self.cursor.execute(sql, params)
65
C:\Users\Jordon\AppData\Local\Programs\Python\Python35\lib\site-packages\django\db\backends\sqlite3\base.py in execute(self, query, params)
322 query = self.convert_query(query)
--> 323 return Database.Cursor.execute(self, query, params)
324
OperationalError: table snippets_snippet has no column named owner_id
The above exception was the direct cause of the following exception:
OperationalError Traceback (most recent call last)
<ipython-input-6-fe28bd3dc796> in <module>()
----> 1 snippet.save()
D:\GitHub Repositories\Django\tutorial\snippets\models.py in save(self, *args, **kwargs)
34 full=True, **options)
35 self.highlighted = highlight(self.code, lexer, formatter)
---> 36 super(Snippet, self).save(*args, **kwargs)
C:\Users\Jordon\AppData\Local\Programs\Python\Python35\lib\site-packages\django\db\models\base.py in save(self, force_insert, force_update, using, update_fields)
698
699 self.save_base(using=using, force_insert=force_insert,
--> 700 force_update=force_update, update_fields=update_fields)
701 save.alters_data = True
702
C:\Users\Jordon\AppData\Local\Programs\Python\Python35\lib\site-packages\django\db\models\base.py in save_base(self, raw, force_insert, force_update, using, update_fields)
726 if not raw:
727 self._save_parents(cls, using, update_fields)
--> 728 updated = self._save_table(raw, cls, force_insert, force_update, using, update_fields)
729 # Store the database on which the object was saved
730 self._state.db = using
C:\Users\Jordon\AppData\Local\Programs\Python\Python35\lib\site-packages\django\db\models\base.py in _save_table(self, raw, cls, force_insert, force_update, using, update_fields)
810
811 update_pk = bool(meta.has_auto_field and not pk_set)
--> 812 result = self._do_insert(cls._base_manager, using, fields, update_pk, raw)
813 if update_pk:
814 setattr(self, meta.pk.attname, result)
C:\Users\Jordon\AppData\Local\Programs\Python\Python35\lib\site-packages\django\db\models\base.py in _do_insert(self, manager, using, fields, update_pk, raw)
849 """
850 return manager._insert([self], fields=fields, return_id=update_pk,
--> 851 using=using, raw=raw)
852
853 def delete(self, using=None, keep_parents=False):
C:\Users\Jordon\AppData\Local\Programs\Python\Python35\lib\site-packages\django\db\models\manager.py in manager_method(self, *args, **kwargs)
120 def create_method(name, method):
121 def manager_method(self, *args, **kwargs):
--> 122 return getattr(self.get_queryset(), name)(*args, **kwargs)
123 manager_method.__name__ = method.__name__
124 manager_method.__doc__ = method.__doc__
C:\Users\Jordon\AppData\Local\Programs\Python\Python35\lib\site-packages\django\db\models\query.py in _insert(self, objs, fields, return_id, raw, using)
1037 query = sql.InsertQuery(self.model)
1038 query.insert_values(fields, objs, raw=raw)
-> 1039 return query.get_compiler(using=using).execute_sql(return_id)
1040 _insert.alters_data = True
1041 _insert.queryset_only = False
C:\Users\Jordon\AppData\Local\Programs\Python\Python35\lib\site-packages\django\db\models\sql\compiler.py in execute_sql(self, return_id)
1058 with self.connection.cursor() as cursor:
1059 for sql, params in self.as_sql():
-> 1060 cursor.execute(sql, params)
1061 if not (return_id and cursor):
1062 return
C:\Users\Jordon\AppData\Local\Programs\Python\Python35\lib\site-packages\django\db\backends\utils.py in execute(self, sql, params)
77 start = time()
78 try:
---> 79 return super(CursorDebugWrapper, self).execute(sql, params)
80 finally:
81 stop = time()
C:\Users\Jordon\AppData\Local\Programs\Python\Python35\lib\site-packages\django\db\backends\utils.py in execute(self, sql, params)
62 return self.cursor.execute(sql)
63 else:
---> 64 return self.cursor.execute(sql, params)
65
66 def executemany(self, sql, param_list):
C:\Users\Jordon\AppData\Local\Programs\Python\Python35\lib\site-packages\django\db\utils.py in __exit__(self, exc_type, exc_value, traceback)
93 if dj_exc_type not in (DataError, IntegrityError):
94 self.wrapper.errors_occurred = True
---> 95 six.reraise(dj_exc_type, dj_exc_value, traceback)
96
97 def __call__(self, func):
C:\Users\Jordon\AppData\Local\Programs\Python\Python35\lib\site-packages\django\utils\six.py in reraise(tp, value, tb)
683 value = tp()
684 if value.__traceback__ is not tb:
--> 685 raise value.with_traceback(tb)
686 raise value
687
C:\Users\Jordon\AppData\Local\Programs\Python\Python35\lib\site-packages\django\db\backends\utils.py in execute(self, sql, params)
62 return self.cursor.execute(sql)
63 else:
---> 64 return self.cursor.execute(sql, params)
65
66 def executemany(self, sql, param_list):
C:\Users\Jordon\AppData\Local\Programs\Python\Python35\lib\site-packages\django\db\backends\sqlite3\base.py in execute(self, query, params)
321 return Database.Cursor.execute(self, query)
322 query = self.convert_query(query)
--> 323 return Database.Cursor.execute(self, query, params)
324
325 def executemany(self, query, param_list):
OperationalError: table snippets_snippet has no column named owner_id
答案 0 :(得分:1)
首先,在保存Snippet对象时,您没有为“所有者”提供值。你需要做这样的事情:
from django.contrib.auth.models import User
new_user = User.objects.create(...)
snippet = Snippet(owner=new_user, code='foo = "bar"\n')
snippet.save()
尽管如此,它并没有解释为什么没有创建owner_id列。您能否将模型更改为此类型,并查看它是否检测到所有者列?
from django.contrib.auth.models import User
class Snippet(models.Model):
owner = models.ForeignKey(User, related_name='snippets')
...
然后运行这些步骤以尝试创建列。
python manage.py makemigrations snippets
python manage.py migrate
答案 1 :(得分:0)
看起来你没有删除原始数据库。
教程在模型更改后将其删除:
rm -f tmp.db db.sqlite3
rm -r snippets/migrations
python manage.py makemigrations snippets
python manage.py migrate
如果你没有删除tmp.db或db.sqlite3,那么Django可能会认为它已经完成了迁移并且不会重做它。
确保找到上述两个文件之一并将其删除,然后运行上述脚本(以及您登录的createsuperuser)。