我正在将Django中的旧项目从版本1.3升级到版本1.9。 我能够管理一些错误并进行修改,但现在我陷入了一个我不明白的错误。django从1.3升级到1.9生成TypeError:“from list”中的项不是字符串
以下是错误日志:
Performing system checks...
/home/norore/.virtualenvs/jebifdjango/local/lib/python2.7/site-packages/django/template/utils.py:37: RemovedInDjango110Warning: You haven't defined a TEMPLATES setting. You must do so before upgrading to Django 1.10. Otherwise Django will be unable to load templates.
"unable to load templates.", RemovedInDjango110Warning)
Unhandled exception in thread started by <function wrapper at 0x7fee03cfb848>
Traceback (most recent call last):
File "/home/norore/.virtualenvs/jebifdjango/local/lib/python2.7/site-packages/django/utils/autoreload.py", line 226, in wrapper
fn(*args, **kwargs)
File "/home/norore/.virtualenvs/jebifdjango/local/lib/python2.7/site-packages/django/core/management/commands/runserver.py", line 116, in inner_run
self.check(display_num_errors=True)
File "/home/norore/.virtualenvs/jebifdjango/local/lib/python2.7/site-packages/django/core/management/base.py", line 426, in check
include_deployment_checks=include_deployment_checks,
File "/home/norore/.virtualenvs/jebifdjango/local/lib/python2.7/site-packages/django/core/checks/registry.py", line 75, in run_checks
new_errors = check(app_configs=app_configs)
File "/home/norore/.virtualenvs/jebifdjango/local/lib/python2.7/site-packages/django/core/checks/urls.py", line 10, in check_url_config
return check_resolver(resolver)
File "/home/norore/.virtualenvs/jebifdjango/local/lib/python2.7/site-packages/django/core/checks/urls.py", line 19, in check_resolver
for pattern in resolver.url_patterns:
File "/home/norore/.virtualenvs/jebifdjango/local/lib/python2.7/site-packages/django/utils/functional.py", line 33, in __get__
res = instance.__dict__[self.name] = self.func(instance)
File "/home/norore/.virtualenvs/jebifdjango/local/lib/python2.7/site-packages/django/core/urlresolvers.py", line 417, in url_patterns
patterns = getattr(self.urlconf_module, "urlpatterns", self.urlconf_module)
File "/home/norore/.virtualenvs/jebifdjango/local/lib/python2.7/site-packages/django/utils/functional.py", line 33, in __get__
res = instance.__dict__[self.name] = self.func(instance)
File "/home/norore/.virtualenvs/jebifdjango/local/lib/python2.7/site-packages/django/core/urlresolvers.py", line 410, in urlconf_module
return import_module(self.urlconf_name)
File "/usr/lib/python2.7/importlib/__init__.py", line 37, in import_module
__import__(name)
File "/home/norore/programmation/jebifdjango/jebif-root/jebif/urls.py", line 22, in <module>
(r'^election/', include('election.urls')),
File "/home/norore/.virtualenvs/jebifdjango/local/lib/python2.7/site-packages/django/conf/urls/__init__.py", line 52, in include
urlconf_module = import_module(urlconf_module)
File "/usr/lib/python2.7/importlib/__init__.py", line 37, in import_module
__import__(name)
File "/home/norore/programmation/jebifdjango/jebif-root/election/urls.py", line 5, in <module>
from election.views import *
File "/home/norore/programmation/jebifdjango/jebif-root/election/views.py", line 3, in <module>
from django.core.mail import *
TypeError: Item in ``from list'' not a string
所以,我查了选举/ urls.py模块和I did'nt看看什么是错的。这里是源代码:
from django.conf.urls import *
from django.views.generic import TemplateView
from election.views import *
urlpatterns = patterns('',
('^(?P<election_id>\d+)/$', vote),
('^(?P<election_id>\d+)/ok/$', TemplateView.as_view(template = "election/vote-ok.html")),
('^(?P<election_id>\d+)/results/$', results),
('^(?P<election_id>\d+)/mailing/$', mailing),
)
而且我也查了选举/ views.py模块:
(?很难直接在计算器上阅读下面是我的帐户GitHub的源代码:https://github.com/Norore/jebif-election/blob/master/views.py)
# -*- coding: utf-8
from django.core.mail import *
from django.shortcuts import *
from django import forms
from django.core.exceptions import ValidationError
from django.contrib.auth.decorators import user_passes_test
from django.contrib.sites.models import Site
from jebif import settings
import election.models as election
import datetime
import operator
def vote(request, election_id) :
el = election.Election.objects.get(id=election_id)
if not el.opened :
return render(request, "election/vote-closed.html")
candidate_choices = [(c.id, c.label) for c in el.candidate.all()]
def validate_candidates(value) :
if len(value) < el.min_choices :
raise ValidationError(u"Sélectionnez au moins %d candidat(s)." % el.min_choices)
if len(value) > el.max_choices :
raise ValidationError(u"Sélectionnez au plus %d candidat(s)." % el.max_choices)
def validate_passwd(value) :
if len(value) != 32 :
raise ValidationError(u"Clef de vote invaide.")
try :
v = el.voter.get(passwd=value)
if v.hasvoted :
raise ValidationError(u"Clef de vote déjà utilisée.")
except election.Voter.DoesNotExist :
raise ValidationError(u"Clef de vote inconnue.")
class VoteForm(forms.Form) :
voteA = forms.ChoiceField(label=u"Vote A : %s" % el.voteA_label, # Bilan moral - \"Approuvez vous le bilan moral de l'association ?\"",
choices=election.Vote._meta.get_field("voteA").choices,
widget=forms.RadioSelect)
if el.voteB_label :
voteB = forms.ChoiceField(label=u"Vote B : %s" % el.voteB_label, # Bilan financier - \"Approuvez vous le bilan financier de l'association ?\"",
choices=election.Vote._meta.get_field("voteB").choices,
widget=forms.RadioSelect)
if el.max_choices > 0 :
candidates = forms.MultipleChoiceField(label=u"Vote C : Renouvellement du Conseil d'Administration - "
+ u"\"Voulez-vous que la personne suivante fasse partie du Conseil d'Administration ?\""
+ ((u" (%d maximum)" % el.max_choices) if el.max_choices < el.candidate.count()
else u" (sélectionnez tous les candidats que vous souhaitez voir élus)"),
required=False,
choices=candidate_choices,
widget=forms.CheckboxSelectMultiple,
validators=[validate_candidates])
passwd = forms.CharField(label=u"Clef du vote",
max_length=32, min_length=32,
validators=[validate_passwd])
if request.method == 'POST' :
form = VoteForm(request.POST)
if form.is_valid() :
d = form.cleaned_data
trace = "%s %s(%s)" % (datetime.datetime.now(), request.META.get("REMOTE_HOST"),
request.META.get("REMOTE_ADDR"))
voter = el.voter.get(passwd=d["passwd"])
vote = election.Vote(election=el)
vote.trace = trace
vote.voteA = d["voteA"]
vote.voteB = d["voteB"] if "voteB" in d else 0
vote.save()
vote.choices = d["candidates"] if "candidates" in d else []
voter.hasvoted = True
voter.trace = trace
vote.save()
voter.save()
return HttpResponseRedirect("ok/")
else :
form = VoteForm()
context = { "election": el,
"form": form,
}
return render(request, "election/vote.html", context)
def is_admin() :
def validate(u) :
return u.is_authenticated() and u.is_staff
return user_passes_test(validate)
@is_admin()
def results(request, election_id) :
el = election.Election.objects.get(id=election_id)
nb_voters = el.voter.count()
total = el.vote_set.count()
participation = (100.*total)/nb_voters
def make_pc(e, t) :
if t > 0 :
e["pc"] = (100.*e["nb"])/t
else :
e["pc"] = 0.
def make_votes(r) :
get_nb = operator.itemgetter("nb")
r.sort(key=get_nb, reverse=True)
t = sum(map(get_nb, r))
for e in r :
make_pc(e,t)
return t
def make_abstained(e) :
make_pc(e, total)
def tristate_result(field) :
r = []
a = None
for (val, label) in election.Vote._meta.get_field(field).choices :
d = {"value": val, "label": label, "nb": el.vote_set.filter(**{field: val}).count()}
if val != 0 :
r.append(d)
else :
a = d
make_votes(r)
make_abstained(a)
return {"votes": r, "abstained": a}
aC_nb = el.vote_set.exclude(choices__in=el.candidate.all()).count()
aC = {"nb": aC_nb}
make_abstained(aC)
base = total - aC_nb
rC = []
for c in el.candidate.all() :
nb = c.vote_set.count()
rC.append({"candidate" : c, "pc": (100.*nb)/base, "nb": nb })
rC.sort(key=operator.itemgetter("pc"), reverse=True)
results = {
"voteA" : tristate_result("voteA"),
"voteB" : tristate_result("voteB"),
"voteC" : {"votes": rC, "abstained": aC}
}
context = { "election": el,
"nb_voters": nb_voters,
"participation": participation,
"total": total,
"results": results,
}
return render(request, "election/results.html", context)
@is_admin()
def mailing(request, election_id) :
el = election.Election.objects.get(id=election_id)
def validate_template(value) :
if not "%ELECTION_PASSWD%" in value or not "%ELECTION_URL%" in value :
raise ValidationError(u"Macros %ELECTION_URL% ou %ELECTION_PASSWD non présentes")
class MailingForm(forms.Form) :
email_to = forms.ChoiceField(label=u"Destinataires", choices=[
("hasnotvoted", u"Seuls les inscrits n'ayant pas voté"),
("allvoters", u"Tous les inscrits au vote"),])
email_from = forms.EmailField(label=u"Expéditeur", initial="[email protected]")
email_subject = forms.CharField(label=u"Sujet", initial="[JeBiF] ")
email_template = forms.CharField(label=u"Modèle du message",
widget=forms.Textarea(attrs={'cols': 90, 'rows': 30}),
help_text="Utiliser les macros %ELECTION_URL% et %ELECTION_PASSWD%. Optionnellement: %VOTER_FIRSTNAME%.",
validators=[validate_template])
attachment1 = forms.FileField(label=u"Attachement 1", required=False)
attachment2 = forms.FileField(label=u"Attachement 2", required=False)
def template_instance(tmpl, voter) :
ELECTION_URL = "http://%s%s" % (Site.objects.get_current().domain, el.get_absolute_url())
return tmpl.replace("%ELECTION_URL%", ELECTION_URL).replace(
"%ELECTION_PASSWD%", voter.passwd).replace(
"%VOTER_FIRSTNAME%", voter.member.firstname)
message = None
mode = "init"
voters = None
if request.method == "POST" :
form = MailingForm(request.POST, request.FILES)
if form.is_valid() :
d = form.cleaned_data
message = {
"from": d["email_from"],
"subject": d["email_subject"],
"attachment1" : d["attachment1"],
"attachment2" : d["attachment2"],
}
if d["email_to"] == "hasnotvoted":
voters = el.voter.filter(hasvoted=False)
else :
voters = el.voter.all()
if "do_it" in request.POST :
def prep_attach(uf) :
if uf :
return { "name": uf.name, "data": uf.read(), "content_type": uf.content_type }
message["attachment1"] = prep_attach(message["attachment1"])
message["attachment2"] = prep_attach(message["attachment2"])
for voter in voters :
msg_txt = template_instance(d["email_template"], voter)
email = EmailMessage(message["subject"], msg_txt, message["from"],
[voter.member.email])
def attach(uf) :
if uf :
email.attach(uf["name"], uf["data"], uf["content_type"])
attach(message["attachment1"])
attach(message["attachment2"])
email.send()
context = { "election": el,
"voters": voters,
}
return render(request, "election/mailing-ok.html", context)
else :
mode = "preview"
class member :
firstname = u"Loïc"
m = member()
class voter :
passwd = "PASSWD_TEST"
member = m
message["preview"] = template_instance(d["email_template"], voter())
else :
form = MailingForm()
context = { "election": el,
"voters": voters,
"form": form,
"mode": mode,
"message": message,
}
return render(request, "election/mailing-form.html", context)
我检查了提到的行,如果我记得不错,但显然他们没有从Django 1.3改变。
你们谁都知道问题是什么?我知道这将是一个长期的升级任务,但我们真的需要升级我们的应用程序!
我也向所有可以与我分享的好建议开放,以便进行升级!
在此先感谢。
您应该包括涉及您的问题代码的相关部分。 – Sayse
1.3至1.9是一个巨大的升级。理想情况下,您可以逐步浏览各个版本并逐一修复问题。如果这不切实际,请尝试升级到1.8。这是一个长期支持版本,所以在升级到1.9(或直接到下一个LTS,1.11)之前,你需要一些时间。 – Alasdair
除了Alasdair的建议之外,我还强调你需要在每个步骤中检查向后不兼容的更改,并在继续前进之前对代码应用任何必要的更改。有了这样一个旧网站,你也可以考虑从全新安装任何你决定选择的Django版本开始,添加你的应用并根据当前的项目结构进行连接,我认为自1.3版本以来它发生了显着变化。 – kungphu