Before I get the obvious response, about checking the database, itself, I'll start by saying that I've already checked out this post, which has a nearly identical setup to mine, and the solutions of deleting the database and migrations, and adding a default value in the table did not work, as expected. I do, however, expect the solution to be quite simple.
So, that said, I'm doing the tutorial for django-rest-framework and my problem started on part 4. The tutorial says as follows:
Now if you open up the browser again and refresh the page you'll see a 'Login' link in the top right of the page. If you log in as one of the users you created earlier, you'll be able to create code snippets again.
Once you've created a few code snippets, navigate to the '/users/' endpoint, and notice that the representation includes a list of the snippet pks that are associated with each user, in each user's 'snippets' field.
So, I tried to create the "snippets" objects with the manage.py shell, as in the first part of the tutorial, with the following code:
from snippets.models import Snippet
from snippets.serializers import SnippetSerializer
snippet = Snippet(code='foo = "bar"\n')
snippet.save()
And that's where it ends. .save() triggers the error, which I've printed the traceback for, below.
Using the advice from the previously answered question, I've very slightly changed my setup, but I'm still getting the error. Here's the setup:
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')),
]
and, lastly, the ugly traceback:
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