【发布时间】:2016-07-30 17:42:52
【问题描述】:
在我得到明显的回应之前,关于检查数据库本身,我首先要说我已经检查了this post,它与我的设置几乎相同,以及删除数据库的解决方案和迁移,并且在表中添加默认值没有按预期工作。但是,我确实希望解决方案非常简单。
也就是说,我正在做the tutorial for django-rest-framework,而我的问题始于part 4。教程是这样说的:
现在,如果您再次打开浏览器并刷新页面,您将在页面右上角看到一个“登录”链接。如果您以之前创建的用户之一登录,您将能够再次创建代码 sn-ps。
创建一些代码 sn-ps 后,导航到“/users/” 端点,并注意该表示包括一个列表 与每个用户相关联的 sn-p pks,在每个用户的 'sn-ps' 字段。
所以,我尝试使用 manage.py shell 创建“sn-ps”对象,就像教程的第一部分一样,使用以下代码:
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
/sn-ps/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
【问题讨论】:
-
你试过运行
makemigrations和migrate吗? -
@vmonteco - 是的。正如我之前在我的问题中所述,我最初运行迁移没有问题,直到我在 shell 中点击 .save() 命令。然后我删除了迁移和数据库,我再次运行它们,但同样的问题再次发生。
-
你可以试试
./manage.py makemigrations <name of your app>然后迁移吗? -
我已经这样做了。没有要应用的迁移。
-
是的@vmonteco。除非您明确指定主键,否则 id 会自动添加。
标签: django sqlite django-rest-framework