After a lot of Googling I haven't been able to find anything that resolves my specific issue. This person's problem appears similar to mine, but it's not a migration issue, as python3 manage.py makemigrations
followed by python3 manage.py migrate
doesn't resolve the problem (no error messages), nor did resetting the database to an empty state with python3 manage.py flush
.
在谷歌上搜索了很多次之后,我找不到任何能解决我的问题的方法。这个人的问题看起来和我的问题很相似,但是这并不是一个迁移问题,正如python3所处理的那样。py标记之后是python3管理。py migration没有解决问题(没有错误消息),也没有使用python3 manage将数据库重置为空状态。py冲洗。
The error occurs whenever I create a Scheme without an associated NewUnit or RefurbUnit and try to view or delete it in the admin interface (consequently it becomes undeleteable even in the shell), or when I try to create a new one with a RefurbUnit or NewUnit, in which case it doesn't get created at all.
发生错误当我创建一个方案没有一个相关的NewUnit或RefurbUnit并试图查看或删除它在管理界面(因此变得undeleteable即使在shell),或者当我尝试创建一个新的RefurbUnit或NewUnit,在这种情况下它不会创建。
The project I'm working on is so far not too different to the completed tutorial; the only substantial difference is in views.py for each project's main app. I'll post the error message and the code for both my project's app and for the tutorial's polls app (just for reference, as I can't find an up-to-date pre-completed tutorial project that you can compare my code against):
到目前为止,我正在做的项目与完成的教程并没有太大的不同;唯一的本质区别在于观点。py用于每个项目的主应用程序。我将为我的项目应用程序和教程的poll应用程序发布错误消息和代码(仅供参考,因为我找不到一个最新的预完成的教程项目,您可以将我的代码与之进行比较):
Error Message
Environment:
Request Method: POST
Request URL: http://127.0.0.1:8000/admin/value_calculator/scheme/add/
Django Version: 1.8.3
Python Version: 3.4.0
Installed Applications:
('django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'value_calculator')
Installed Middleware:
('django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
'django.middleware.security.SecurityMiddleware')
Traceback:
File "/usr/local/lib/python3.4/dist-packages/django/core/handlers/base.py" in get_response
132. response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/usr/local/lib/python3.4/dist-packages/django/contrib/admin/options.py" in wrapper
616. return self.admin_site.admin_view(view)(*args, **kwargs)
File "/usr/local/lib/python3.4/dist-packages/django/utils/decorators.py" in _wrapped_view
110. response = view_func(request, *args, **kwargs)
File "/usr/local/lib/python3.4/dist-packages/django/views/decorators/cache.py" in _wrapped_view_func
57. response = view_func(request, *args, **kwargs)
File "/usr/local/lib/python3.4/dist-packages/django/contrib/admin/sites.py" in inner
233. return view(request, *args, **kwargs)
File "/usr/local/lib/python3.4/dist-packages/django/contrib/admin/options.py" in add_view
1516. return self.changeform_view(request, None, form_url, extra_context)
File "/usr/local/lib/python3.4/dist-packages/django/utils/decorators.py" in _wrapper
34. return bound_func(*args, **kwargs)
File "/usr/local/lib/python3.4/dist-packages/django/utils/decorators.py" in _wrapped_view
110. response = view_func(request, *args, **kwargs)
File "/usr/local/lib/python3.4/dist-packages/django/utils/decorators.py" in bound_func
30. return func.__get__(self, type(self))(*args2, **kwargs2)
File "/usr/lib/python3.4/contextlib.py" in inner
30. return func(*args, **kwds)
File "/usr/local/lib/python3.4/dist-packages/django/contrib/admin/options.py" in changeform_view
1468. self.save_related(request, form, formsets, not add)
File "/usr/local/lib/python3.4/dist-packages/django/contrib/admin/options.py" in save_related
1102. self.save_formset(request, form, formset, change=change)
File "/usr/local/lib/python3.4/dist-packages/django/contrib/admin/options.py" in save_formset
1090. formset.save()
File "/usr/local/lib/python3.4/dist-packages/django/forms/models.py" in save
640. return self.save_existing_objects(commit) + self.save_new_objects(commit)
File "/usr/local/lib/python3.4/dist-packages/django/forms/models.py" in save_new_objects
771. self.new_objects.append(self.save_new(form, commit=commit))
File "/usr/local/lib/python3.4/dist-packages/django/forms/models.py" in save_new
904. obj.save()
File "/usr/local/lib/python3.4/dist-packages/django/db/models/base.py" in save
710. force_update=force_update, update_fields=update_fields)
File "/usr/local/lib/python3.4/dist-packages/django/db/models/base.py" in save_base
738. updated = self._save_table(raw, cls, force_insert, force_update, using, update_fields)
File "/usr/local/lib/python3.4/dist-packages/django/db/models/base.py" in _save_table
822. result = self._do_insert(cls._base_manager, using, fields, update_pk, raw)
File "/usr/local/lib/python3.4/dist-packages/django/db/models/base.py" in _do_insert
861. using=using, raw=raw)
File "/usr/local/lib/python3.4/dist-packages/django/db/models/manager.py" in manager_method
127. return getattr(self.get_queryset(), name)(*args, **kwargs)
File "/usr/local/lib/python3.4/dist-packages/django/db/models/query.py" in _insert
920. return query.get_compiler(using=using).execute_sql(return_id)
File "/usr/local/lib/python3.4/dist-packages/django/db/models/sql/compiler.py" in execute_sql
974. cursor.execute(sql, params)
File "/usr/local/lib/python3.4/dist-packages/django/db/backends/utils.py" in execute
79. return super(CursorDebugWrapper, self).execute(sql, params)
File "/usr/local/lib/python3.4/dist-packages/django/db/backends/utils.py" in execute
64. return self.cursor.execute(sql, params)
File "/usr/local/lib/python3.4/dist-packages/django/db/utils.py" in __exit__
97. six.reraise(dj_exc_type, dj_exc_value, traceback)
File "/usr/local/lib/python3.4/dist-packages/django/utils/six.py" in reraise
658. raise value.with_traceback(tb)
File "/usr/local/lib/python3.4/dist-packages/django/db/backends/utils.py" in execute
64. return self.cursor.execute(sql, params)
Exception Type: ProgrammingError at /admin/value_calculator/scheme/add/
Exception Value: column "scheme_id" of relation "value_calculator_newunit" does not exist
LINE 1: INSERT INTO "value_calculator_newunit" ("scheme_id", "D", "f...
^
My app's code
admin.py
from django.contrib import admin
from .models import Scheme, NewUnit, RefurbUnit
class NewUnitInline(admin.TabularInline):
model = NewUnit
extra = 0
class RefurbUnitInline(admin.TabularInline):
model = RefurbUnit
extra = 0
class SchemeAdmin(admin.ModelAdmin):
#fieldsets = [
# (None, {'fields': ['name']}),
# ('Date information', {'fields': ['date']}),
#]
inlines = [NewUnitInline, RefurbUnitInline]
list_display = ("name", "date")
list_filter = ["date"]
admin.site.register(Scheme, SchemeAdmin)
models.py
from django.db import models
class Scheme(models.Model):
#scheme_id = models.IntegerField(unique=True, primary_key=True) #Makes absolutely no difference.
name = models.CharField(max_length=200)
new_units = models.IntegerField(default=0)
refurb_units = models.IntegerField(default=0)
date = models.DateTimeField()
appraiser = models.CharField(max_length=200, default="Nobody", blank=True)
#FIXME: This method is now broken due to ForeignKeys in NewUnit and RefurbUnit
def get_fields(self):
return [(field.name, field.value_to_string(self)) for field in self._meta.get_fields()]
def __str__(self):
return self.name
class NewUnit(models.Model):
scheme = models.ForeignKey(Scheme)
D = models.CharField(max_length=200)
floor_area = models.IntegerField(default=0)
units = models.IntegerField(default=0)
build_price_per_m2 = models.FloatField(default=0)
build_price_per_unit = models.FloatField(default=0)
affordable_ratio = models.FloatField(default=0) #Actually a percentage field rather than ratio
class RefurbUnit(models.Model):
scheme = models.ForeignKey(Scheme)
resale_price = models.FloatField()
selling_costs = models.FloatField() #This is percentage, and paired with below field which is an absolute figure
legal_costs = models.FloatField()
refurbishment_costs = models.FloatField()
other_costs = models.FloatField()
urls.py
from django.conf.urls import url
from . import views
urlpatterns = [
url(r'^$', views.index, name='index'),
url(r'^(?P<scheme_id>[0-9]+)/$', views.detail, name='detail'),
]
views.py
from django.shortcuts import render, get_object_or_404
from django.http import HttpResponse, Http404
from .models import Scheme, NewUnit, RefurbUnit
def index(request):
scheme_list = Scheme.objects.order_by("-date")[:5]
context = {"scheme_list": scheme_list}
return render(request, "value_calculator/index.html", context)
def detail(request, scheme_id):
scheme = get_object_or_404(Scheme, pk=scheme_id)
return render(request, "value_calculator/detail.html", {"scheme": scheme})
tests.py
import datetime
from django.test import TestCase
from django.core.urlresolvers import reverse
from django.utils import timezone
from .models import Scheme, NewUnit, RefurbUnit
def create_scheme(name, days=0, new_units=0, refurb_units=0, appraiser=""):
"""Days is an offset value from the current date"""
time = timezone.now() + datetime.timedelta(days=days)
return Scheme.objects.create(name=name, date=time, new_units=new_units, refurb_units=refurb_units, appraiser=appraiser)
class SchemeMethodTests(TestCase):
def test_get_fields(self):
"""Test that the types and lengths are correct."""
scheme = create_scheme("Test")
data = scheme.get_fields()
print(data)
self.assertEqual(len(data), 6)
self.assertEqual(type(data), list)
for item in data:
self.assertEqual(type(item), tuple)
class SchemeViewTests(TestCase):
def test_index_view_with_no_schemes(self):
response = self.client.get(reverse('value_calculator:index'))
self.assertEqual(response.status_code, 200)
self.assertContains(response, "No schemes are available. Please add some via the admin page.")
self.assertQuerysetEqual(response.context['scheme_list'], [])
def test_index_view_with_past_date(self):
create_scheme("Past scheme", days=-30)
response = self.client.get(reverse('value_calculator:index'))
self.assertQuerysetEqual(
response.context["scheme_list"],
["<Scheme: Past scheme>"]
)
def test_index_view_with_future_date(self):
create_scheme("Future scheme", days=30)
response = self.client.get(reverse('value_calculator:index'))
self.assertQuerysetEqual(
response.context["scheme_list"],
["<Scheme: Future scheme>"]
)
Tutorial's polls app code
admin.py
from django.contrib import admin
from .models import Choice, Question
class ChoiceInline(admin.TabularInline):
model = Choice
extra = 3
class QuestionAdmin(admin.ModelAdmin):
fieldsets = [
(None, {'fields': ['question_text']}),
('Date information', {'fields': ['pub_date']}),
]
inlines = [ChoiceInline]
list_display = ('question_text', 'pub_date', 'was_published_recently')
list_filter = ['pub_date']
search_fields = ['question_text']
admin.site.register(Question, QuestionAdmin)
models.py
import datetime
from django.utils import timezone
from django.db import models
# Create your models here.
class Question(models.Model):
def __str__(self):
return self.question_text
def was_published_recently(self):
now = timezone.now()
return now - datetime.timedelta(days=1) <= self.pub_date <= now
was_published_recently.admin_order_field = 'pub_date'
was_published_recently.boolean = True
was_published_recently.short_description = 'Published recently?'
question_text = models.CharField(max_length=200)
pub_date = models.DateTimeField('date published')
class Choice(models.Model):
def __str__(self):
return self.choice_text
question = models.ForeignKey(Question)
choice_text = models.CharField(max_length=200)
votes = models.IntegerField(default=0)
urls.py
from django.conf.urls import url
from . import views
urlpatterns = [
# ex: /polls
url(r'^$', views.index, name='index'),
# ex: /polls/5
url(r'^(?P<question_id>[0-9]+)/$', views.detail, name='detail'),
# ex: /polls/5/results/
url(r'^(?P<question_id>[0-9]+)/results/$', views.results, name='results'),
# ex: /polls/5/vote/
url(r'^(?P<question_id>[0-9]+)/vote/$', views.vote, name='vote'),
]
views.py
from django.shortcuts import render, get_object_or_404
from django.http import HttpResponse, Http404, HttpResponseRedirect
from django.core.urlresolvers import reverse
from django.template import RequestContext, loader
from django.utils import timezone
from django.views import generic
from .models import Choice, Question
class IndexView(generic.ListView):
template_name = 'polls/index.html'
context_object_name = 'latest_question_list'
def get_queryset(self):
"""Return the last five published questions."""
return Question.objects.filter(
pub_date__lte=timezone.now()
).order_by('-pub_date')[:5]
class DetailView(generic.DetailView):
model = Question
template_name = 'polls/detail.html'
def get_queryset(self):
"""
Excludes any questions that aren't published yet.
"""
return Question.objects.filter(pub_date__lte=timezone.now())
class ResultsView(generic.DetailView):
model = Question
template_name = 'polls/results.html'
def index(request):
latest_question_list = Question.objects.order_by('-pub_date')[:5]
context = {'latest_question_list': latest_question_list}
return render(request, 'polls/index.html', context)
def detail(request, question_id):
question = get_object_or_404(Question, pk=question_id)
return render(request, 'polls/detail.html', {'question': question})
def results(request, question_id):
response = "You're looking at the results of question %s."
return HttpResponse(response % question_id)
def vote(request, question_id):
p = get_object_or_404(Question, pk=question_id)
try:
selected_choice = p.choice_set.get(pk=request.POST['choice'])
except (KeyError, Choice.DoesNotExist):
# Redisplay the question voting form.
return render(request, 'polls/detail.html', {
'question': p,
'error_message': "You didn't select a choice.",
})
else:
selected_choice.votes += 1
selected_choice.save()
# Always return an HttpResponseRedirect after successfully dealing
# with POST data. This prevents data from being posted twice if a
# user hits the Back button.
return HttpResponseRedirect(reverse('polls:results', args=(p.id,)))
tests.py
import datetime
from django.utils import timezone
from django.test import TestCase
from django.core.urlresolvers import reverse
from .models import Question
def create_question(question_text, days):
"""
Creates a question with the given `question_text` published the given
number of `days` offset to now (negative for questions published
in the past, positive for questions that have yet to be published).
"""
time = timezone.now() + datetime.timedelta(days=days)
return Question.objects.create(question_text=question_text,
pub_date=time)
class QuestionViewTests(TestCase):
def test_index_view_with_no_questions(self):
"""
If no questions exist, an appropriate message should be displayed.
"""
response = self.client.get(reverse('polls:index'))
self.assertEqual(response.status_code, 200)
self.assertContains(response, "No polls are available.")
self.assertQuerysetEqual(response.context['latest_question_list'], [])
def test_index_view_with_a_past_question(self):
"""
Questions with a pub_date in the past should be displayed on the
index page.
"""
create_question(question_text="Past question.", days=-30)
response = self.client.get(reverse('polls:index'))
self.assertQuerysetEqual(
response.context['latest_question_list'],
['<Question: Past question.>']
)
def test_index_view_with_a_future_question(self):
"""
Questions with a pub_date in the future should not be displayed on
the index page.
"""
create_question(question_text="Future question.", days=30)
response = self.client.get(reverse('polls:index'))
self.assertContains(response, "No polls are available.",
status_code=200)
self.assertQuerysetEqual(response.context['latest_question_list'], [])
def test_index_view_with_future_question_and_past_question(self):
"""
Even if both past and future questions exist, only past questions
should be displayed.
"""
create_question(question_text="Past question.", days=-30)
create_question(question_text="Future question.", days=30)
response = self.client.get(reverse('polls:index'))
self.assertQuerysetEqual(
response.context['latest_question_list'],
['<Question: Past question.>']
)
def test_index_view_with_two_past_questions(self):
"""
The questions index page may display multiple questions.
"""
create_question(question_text="Past question 1.", days=-30)
create_question(question_text="Past question 2.", days=-5)
response = self.client.get(reverse('polls:index'))
self.assertQuerysetEqual(
response.context['latest_question_list'],
['<Question: Past question 2.>', '<Question: Past question 1.>']
)
class QuestionMethodTests(TestCase):
def test_was_published_recently_with_future_question(self):
"""
was_published_recently() should return False for questions whose
pub_date is in the future.
"""
time = timezone.now() + datetime.timedelta(days=30)
future_question = Question(pub_date=time)
self.assertEqual(future_question.was_published_recently(), False)
def test_was_published_recently_with_old_question(self):
"""
was_published_recently() should return False for questions whose
pub_date is older than 1 day.
"""
time = timezone.now() - datetime.timedelta(days=30)
old_question = Question(pub_date=time)
self.assertEqual(old_question.was_published_recently(), False)
def test_was_published_recently_with_recent_question(self):
"""
was_published_recently() should return True for questions whose
pub_date is within the last day.
"""
time = timezone.now() - datetime.timedelta(hours=1)
recent_question = Question(pub_date=time)
self.assertEqual(recent_question.was_published_recently(), True)
class QuestionIndexDetailTests(TestCase):
def test_detail_view_with_a_future_question(self):
"""
The detail view of a question with a pub_date in the future should
return a 404 not found.
"""
future_question = create_question(question_text='Future question.',
days=5)
response = self.client.get(reverse('polls:detail',
args=(future_question.id,)))
self.assertEqual(response.status_code, 404)
def test_detail_view_with_a_past_question(self):
"""
The detail view of a question with a pub_date in the past should
display the question's text.
"""
past_question = create_question(question_text='Past Question.',
days=-5)
response = self.client.get(reverse('polls:detail',
args=(past_question.id,)))
self.assertContains(response, past_question.question_text,
status_code=200)
Also, I'm running Linux Mint 17.2 and PostgreSQL 9.3.9.
另外,我正在运行Linux Mint 17.2和PostgreSQL 9.3.9。
1 个解决方案
#1
1
I found that the problem was with my database in PostgreSQL, although unfortunately I don't know what exactly went wrong. I simply dropped and re-created it with dropdb
and createdb
, then ran manage.py migrate
; my assumption that manage.py flush
would clear absolutely everything was faulty.
我发现问题出在我的PostgreSQL数据库上,尽管不幸的是我不知道到底哪里出错了。我只是简单地删除并重新创建它与dropdb和createdb,然后运行管理。py迁移;我认为管理。py脸红会表明一切都是错误的。
Thanks to Daniel Roseman for leading me to the solution by pointing out that it could only be a migration issue.
感谢Daniel Roseman带领我找到了解决方案,指出这可能只是一个迁移问题。
#1
1
I found that the problem was with my database in PostgreSQL, although unfortunately I don't know what exactly went wrong. I simply dropped and re-created it with dropdb
and createdb
, then ran manage.py migrate
; my assumption that manage.py flush
would clear absolutely everything was faulty.
我发现问题出在我的PostgreSQL数据库上,尽管不幸的是我不知道到底哪里出错了。我只是简单地删除并重新创建它与dropdb和createdb,然后运行管理。py迁移;我认为管理。py脸红会表明一切都是错误的。
Thanks to Daniel Roseman for leading me to the solution by pointing out that it could only be a migration issue.
感谢Daniel Roseman带领我找到了解决方案,指出这可能只是一个迁移问题。