Je suis très nouveau sur Django et j'ai pu terminer le didacticiel sur djangoproject.com sans erreur. Je suis en train de parcourir le didacticiel relatif à la structure Django REST disponible à l'adresse http://www.Django-rest-framework.org/ J'en ai presque fini et j'ai simplement ajouté l'authentification. Maintenant j'obtiens:
OperationalError at /snippets/
no such column: snippets_snippet.owner_id
Request Method: GET
Request URL: http://localhost:8000/snippets/
Django Version: 1.7
Exception Type: OperationalError
Exception Value:
no such column: snippets_snippet.owner_id
Exception Location: /Users/taylorallred/Desktop/env/lib/python2.7/site-packages/Django/db/backends/sqlite3/base.py in execute, line 485
Python Executable: /Users/taylorallred/Desktop/env/bin/python
Python Version: 2.7.5
Python Path:
['/Users/taylorallred/Desktop/tutorial',
'/Users/taylorallred/Desktop/env/lib/python27.Zip',
'/Users/taylorallred/Desktop/env/lib/python2.7',
'/Users/taylorallred/Desktop/env/lib/python2.7/plat-darwin',
'/Users/taylorallred/Desktop/env/lib/python2.7/plat-mac',
'/Users/taylorallred/Desktop/env/lib/python2.7/plat-mac/lib-scriptpackages',
'/Users/taylorallred/Desktop/env/Extras/lib/python',
'/Users/taylorallred/Desktop/env/lib/python2.7/lib-tk',
'/Users/taylorallred/Desktop/env/lib/python2.7/lib-old',
'/Users/taylorallred/Desktop/env/lib/python2.7/lib-dynload',
'/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7',
'/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/plat-darwin',
'/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/lib-tk',
'/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/plat-mac',
'/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/plat-mac/lib-scriptpackages',
'/Users/taylorallred/Desktop/env/lib/python2.7/site-packages']
Server time: Sat, 11 Oct 2014 07:02:34 +0000
J'ai cherché à plusieurs endroits sur le Web, pas seulement stackoverflow, il semble qu'en général le problème vient de ma base de données et qu'il faille le supprimer puis le refaire, je l'ai déjà fait plusieurs fois, le didacticiel m'a même supprimer la base de données et la refaire au point . Voici mon 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()
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):
"""
Use the 'pygments' library to create a highlighted HTML
representation of the code snippet.
"""
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)
Mon serializers.py
:
from Django.forms import widgets
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.Field(source='owner.username')
class Meta:
model = Snippet
fields = ('id', 'title', 'code', 'linenos', 'language', 'style', 'owner')
class UserSerializer(serializers.ModelSerializer):
snippets = serializers.PrimaryKeyRelatedField(many=True)
class Meta:
model = User
fields = ('id', 'username', 'snippets')
Mon views.py
:
from snippets.models import Snippet
from snippets.serializers import SnippetSerializer
from rest_framework import generics
from Django.contrib.auth.models import User
from snippets.serializers import UserSerializer
from rest_framework import permissions
class SnippetList(generics.ListCreateAPIView):
"""
List all snippets, or create a new snippet.
"""
queryset = Snippet.objects.all()
serializer_class = SnippetSerializer
def pre_save(self, obj):
obj.owner = self.request.user
permission_classes = (permissions.IsAuthenticatedOrReadOnly,)
class SnippetDetail(generics.RetrieveUpdateDestroyAPIView):
"""
Retrieve, update or delete a nippet instance.
"""
queryset = Snippet.objects.all()
serializer_class = SnippetSerializer
def pre_save(self, obj):
obj.owner = self.request.user
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
Et enfin mon urls.py
from Django.conf.urls import include
from Django.conf.urls import patterns, url
from rest_framework.urlpatterns import format_suffix_patterns
from snippets import views
urlpatterns = patterns('',
url(r'^snippets/$', views.SnippetList.as_view()),
url(r'^snippets/(?P<pk>[0-9]+)/$', views.SnippetDetail.as_view()),
url(r'^users/$', views.UserList.as_view()),
url(r'^users/(?P<pk>[0-9]+)/$', views.UserDetail.as_view()),
)
urlpatterns = format_suffix_patterns(urlpatterns)
urlpatterns += patterns('',
url(r'^api-auth/', include('rest_framework.urls',
namespace='rest_framework')),
)
Je m'excuse si j'ai posté un tas d'informations inutiles. Merci d'avance les gars.
Edition: Schéma de base de données:
CREATE TABLE "snippets_snippet" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT,
"created" datetime NOT NULL, "title" varchar(100) NOT NULL, "code" text NOT NULL,
"linenos" bool NOT NULL, "language" varchar(100) NOT NULL, "style" varchar(100) NOT NULL);
Après avoir creusé un peu, j’ai trouvé que lors de la suppression et de la recréation de la base de données (comme le dit le didacticiel) au lieu d’utiliser la commande makemigrations
, non seulement cela n’ajoute PAS les colonnes, mais cela ne me dit pas non plus que quelque chose ne va pas, lorsqu’on exécute la commande makemigrations
il me dit:
You are trying to add a non-nullable field 'highlighted' to snippet without a default;
we can't do that (the database needs something to populate existing rows).
Please select a fix:
1) Provide a one-off default now (will be set on all existing rows)
2) Quit, and let me add a default in models.py
Si je commente la section highlighted
dans models.py
, elle affichera le même message ci-dessus mais pour la ligne owner
. Donc, il veut une valeur par défaut à la fois pour highlighted
et owner
, mais je ne suis pas sûr de ce qu'il convient d'utiliser. De plus, le tutoriel ne m'aide pas non plus.
Au cours de ce didacticiel, vous avez probablement rencontré la section sur la migration, qui constituait l'un des changements majeurs de Django 1.7.
Avant Django 1.7, la commande syncdb n’apportait aucune modification susceptible de détruire les données présentes dans la base de données. Cela signifie que si vous avez synchronisé la base de données pour un modèle, puis ajouté une nouvelle ligne au modèle (une nouvelle colonne, effectivement), syncdb n'affectera pas ce changement dans la base de données.
Vous avez donc soit supprimé cette table à la main, puis exécuté à nouveau syncdb (pour le recréer à partir de zéro, en perdant toutes les données), soit vous avez entré manuellement les instructions correctes dans la base de données pour ajouter uniquement cette colonne.
Ensuite, un projet appelé south
a mis en œuvre des migrations. Cela signifiait qu'il y avait un moyen de migrer en avant (et inverser, annuler) toutes les modifications apportées à la base de données et de préserver l'intégrité des données.
Dans Django 1.7, les fonctionnalités de south
ont été intégrées directement dans Django. Lorsque vous travaillez avec des migrations, le processus est un peu différent.
models.py
(comme d'habitude).makemigrations
. Cette commande est suffisamment intelligente pour détecter ce qui a changé et créera un script pour effectuer ce changement dans votre base de données.migrate
. Cette commande applique toutes les migrations dans l'ordre.Donc, votre syncdb
normale est maintenant un processus en deux étapes, python manage.py makemigrations
suivi de python manage.py migrate
.
Passons maintenant à votre problème spécifique:
class Snippet(models.Model):
owner = models.ForeignKey('auth.User', related_name='snippets')
highlighted = models.TextField()
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)
Dans ce modèle, vous avez deux champs highlighted
et code
qui sont obligatoires (ils ne peuvent pas être null).
Si vous aviez ajouté ces champs depuis le début, il n'y aurait pas de problème car la table n'a pas de lignes existantes.
Toutefois, si la table a déjà été créée et que vous ajoutez un champ ne pouvant pas être nul, vous devez définir une valeur par défaut pour fournir les lignes existantes. Dans le cas contraire, la base de données n'acceptera pas vos modifications, car elles violeraient les contraintes d'intégrité des données.
C’est ce que vous demande la commande. Vous pouvez indiquer à Django d’appliquer une valeur par défaut lors de la migration ou de lui donner une valeur "vide" par défaut highlighted = models.TextField(default='')
dans le modèle lui-même.
Concentrons-nous sur l'erreur:
Valeur d'exception: pas de colonne de ce type: snippets_snippet.owner_id
Voyons si c'est vrai ...
Vous pouvez utiliser la commande manage.py pour accéder à votre base de données Shell (cela utilisera les variables settings.py, vous serez donc sûr de vous connecter à la bonne).
manage.py dbshell
Vous pouvez maintenant afficher les détails de votre table en tapant:
.schema TABLE_NAME
Ou dans votre cas:
.schema snippets_snippet
Vous pouvez trouver plus de commandes sqlite ici ou en envoyant un:
.Aidez-moi
Enfin, terminez votre session en tapant:
.quitter
Cela ne vous sort pas du bois, mais vous aide à savoir sur quelle extrémité du problème il faut travailler :)
Bonne chance!
Je vois que nous avons le même problème ici, j'ai la même erreur. Je souhaite écrire ceci pour le futur utilisateur qui rencontrera la même erreur ... Après avoir apporté des modifications au modèle de votre classe Snippet comme @Burhan Khalid, vous devez migrer les tables:
python manage.py makemigrations snippets
python manage.py migrate
Et cela devrait résoudre l'erreur . Enjoy.
Cette erreur peut se produire si vous instanciez une classe qui repose sur cette table, par exemple dans views.py.
Le moyen le plus direct de résoudre ce type de problème consiste à suivre le processus en 3 étapes suivant:
Supprimez tous les fichiers liés à la migration du dossier/répertoire de migrations de l'App (ils commencent par 0000, 0001, 0002, etc.).
Supprimer/Renommer le fichier de base de données existant nommé db.sqlite3 à partir du répertoire App.
Maintenant, lancez la commande suivante:
python manage.py migrate
Enfin exécuter
python manage.py createsuperuser
effectuer les tâches administratives (si vous le souhaitez).
Tiré de la réponse de Burhan Khalid et de son commentaire sur les migrations: ce qui a fonctionné pour moi a été de supprimer le contenu du dossier "migrations" avec la base de données, puis d'exécuter manage.py migrate. La suppression de la base de données n'est pas suffisante en raison des informations enregistrées sur la structure de la table dans le dossier des migrations.
Vous avez tout fait correctement, je suis passé par le même problème . D'abord, supprimez-vous la base de données et les migrations J'ai résolu l'ajout du nom de mon application dans makemigrations
:
python manage.py makemigrations appname
python manage.py migrate
Cela fonctionnera certainement.
D'accord avec Rishikesh. Moi aussi j'ai essayé de résoudre ce problème pendant longtemps. Cela sera résolu avec l'une des deux méthodes, ou les deux.
1. Essayez de supprimer les migrations dans le dossier de migration de l'application (sauf init . Py) puis en exécutant la commande makemigrations
2.Si cela ne fonctionne pas, essayez de renommer le modèle (ceci est le dernier recours et peut devenir un peu brouillon mais fonctionnera à coup sûr. Si Django vous demande "avez-vous renommé le modèle? Appuyez simplement sur N.") aide .. :)
J'ai fait face à ce problème et voici comment je l'ai résolu.
1) Supprimez tous les enregistrements de migration du répertoire de migration de votre application. Ce sont des fichiers nommés 0001_, 0002_, 0003_ etc. Faites attention à ne pas supprimer le fichier _init__.py.
2) Supprimez le fichier db.sqlite3. Il sera régénéré plus tard.
Maintenant, lancez les commandes suivantes:
python manage.py makemigrations appname
python manage.py migrate
Assurez-vous d'écrire le nom de votre application après makemigrations. Vous devrez peut-être créer un superutilisateur pour accéder à votre base de données à nouveau. Faites-le comme suit
python manage.py createsuperuser
Je suis aussi confronté au même problème.
Si vous ajoutez un nouveau champ, l'erreur est indiquée car aucune colonne n'a été trouvée.
Ensuite, vous appliquez la commande make migration
et ensuite la commande migrate
Puis toujours la même erreur .. EX ...
path=models.FilePathField()
Ajouter une valeur par défaut pour le champ
path=models.FilePathField(default='')
et ensuite appliquer la commande
python manage.py makemigrations
python manage.py migrate
Ça peut vous aider
Si votre problème est comme le mien, voici une solution de contournement ... La bonne nouvelle est que vous ne devez pas supprimer votre base de données.
Vérifiez qu’aucun autre modèle n’utilise ce modèle comme référence.
Django.db.utils.OperationalError: no such column: parts_part_type.blah
Cela ne m'arrivait que parce que j'avais un autre modèle appelé "produit" dans une application différente appelée "produits" qui faisait référence à ce modèle.
part = models.ForeignKey("parts.Part", related_name="some part", limit_choices_to={'part_type':Part_Type.objects.get(prefix='PART')},)
Ma solution était:
python manage.py makemigrations; python manage.py migrate
python manage.py makemigrations; python manage.py migrate
Techniquement, je pense que je dois changer la référence limit_choices_to
afin
Au départ, j'ai commenté mes nouveaux champs qui sont à l'origine de ces erreurs, puis je lance python manage.py makemigrations puis python manage.py migrate pour supprimer ces nouveaux champs.
class FootballScore(models.Model):
team = models.ForeignKey(Team, related_name='teams_football', on_delete=models.CASCADE)
# match_played = models.IntegerField(default='0')
# lose = models.IntegerField(default='0')
win = models.IntegerField(default='0')
# points = models.IntegerField(default='0')
class FootballScore(models.Model):
team = models.ForeignKey(Team, related_name='teams_football', on_delete=models.CASCADE)
match_played = models.IntegerField(default='0')
lose = models.IntegerField(default='0')
win = models.IntegerField(default='0')
points = models.IntegerField(default='0')
Ensuite, je les ai récemment commentés et je lance python manage.py makemigrations et python manage.py migrate and boom. Cela a fonctionné pour moi. :)