以前开发php时,一直在使用sae的平台和服务,非常的喜欢。现在在整openstack,所以改用python做一些东西,为了不来回切换两个语言,我决定学习学习django,方便做一些自己的东西。关于sae下python的使用,sae官方文档写的非常全面,我这里只是记录自己的一个学习过程
安装django
easy_install django
下载安装本地开发环境
git clone https://github.com/SAEPython/saepythondevguide.git cd dev_server python setup.py install
到sae.sina.com.cn下创建一个python项目
进入管理面板创建版本,版本号为1
使用svn下载代码
svn co https://svn.sinaapp.com/xxxxx/
进入主目录,发现一个1的文件夹,这个就是对应的django的工程目录
django-admin.py start project mysite mv mysite/* 1
在1下创建配置文件config.yaml,并写入如下内容
libraries: - name: "django" version: "1.4"
在1下创建index.wsgi,内容如下
import sae from mysite import wsgi application = sae.create_wsgi_app(wsgi.application)
项目创建完毕,在1中执行dev_server.py来启动sae项目,默认localhost:8080访问
我在这里遇到一个问题,我是用Windows虚拟的Linux,所以我在Windows下无法通过ip:8080访问到linux。看了d>ev_server.py的代码发现这里host是写死为localhost的,所以我将代码小改动了一下
#/usr/local/lib/python2.7/dist-packages/sae_python_dev.../EGG-INFO/scripts/dev_server.py run_simple(option.host, options.port...) if __name__ == '__main__': parser = Option.Parser() parser.add_option("--host",dest="host",default="localhost")
这样就能通过增加–host,将外部访问的ip设定好了
在1目录下,创建应用
python manage.py startapp polls
修改配置文件settings
import os if 'SERVER_SOFTWARE' in os.environ: from sae.const import( MYSQL_HOST, MYSQL_PORT, MYSQL_USER, MYSQL_PASS, MYSQL_DB ) else: MYSQL_HOST = "localhost" MYSQL_PORT = "3306" MYSQL_USER = "root" MYSQL_PASS = "xxxxx" MYSQL_DB = "app_polls" DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', 'NAME': MYSQL_DB, 'USER': MYSQL_USER, 'PASSWORD': MYSQL_PASS, 'HOST': MYSQL_HOST, 'PORT': MYSQL_PORT, } } ... TEMPLATE_DIRS = ( # Put strings here, like "/home/html/django_templates" or "C:/www/django/templates". # Always use forward slashes, even on Windows. # Don't forget to use absolute paths, not relative paths. os.path.join(os.path.dirname(__file__), 'templates'), ) INSTALLED_APPS = ( 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.sites', 'django.contrib.messages', 'django.contrib.staticfiles', # Uncomment the next line to enable the admin: 'django.contrib.admin', # Uncomment the next line to enable admin documentation: # 'django.contrib.admindocs', 'polls' )
这里的配置项主要是将SAE和本地开发环境区分开,在SAE环境下使用它们提供的变量就可以直接连接数据库了,不过记得要在SAE控制面板进行初始化
配置主urls,即mysite下的urls
from django.conf.urls import patterns, include, url from django.contrib import admin admin.autodiscover() urlpatterns = patterns('', url(r'^admin/', include(admin.site.urls)), url(r'^polls/', include('polls.urls')), )
在polls文件夹下修改urls
from django.conf.urls import patterns, url urlpatterns = patterns('polls.views', url(r'^$', 'index'), url(r'^(?P<poll_id>\d+)/$', 'detail'), url(r'^(?P<poll_id>\d+)/results/$', 'results'), url(r'^(?P<poll_id>\d+)/vote/$', 'vote'), )
在polls文件夹下创建model.py
from django.db import models class Poll(models.Model): question = models.CharField(max_length=200) pub_date = models.DateTimeField('date published') class Choice(models.Model): poll = models.ForeignKey(Poll) choice = models.CharField(max_length=200) votes = models.IntegerField()
然后在mysql中创建一个add_polls数据库,使用
python manage.py syncdb
同步数据库,这个仅限本地,如果要在sae使用的话,需要本地生成后导入到sae上。
在polls文件夹下创建view视图文件
from django.shortcuts import render_to_response, get_object_or_404 from django.template import RequestContext from django.http import HttpResponseRedirect from django.core.urlresolvers import reverse from polls.models import Poll, Choice #主页显示最新的5条投票列表 def index(request): latest_poll_list = Poll.objects.all().order_by('-pub_date')[:5] return render_to_response('index.html', {'latest_poll_list': latest_poll_list}) #获得某条信息详细情况 def detail(request, poll_id): p = get_object_or_404(Poll, pk=poll_id) return render_to_response('detail.html', {'poll': p}, context_instance=RequestContext(request)) #投票 def vote(request, poll_id): p = get_object_or_404(Poll, pk=poll_id) try: selected_choice = p.choice_set.get(pk=request.POST['choice']) except (KeyError, Choice.DoesNotExist): return render_to_response('detail.html', { 'poll': p, 'error_message': "You didn't select a choice.", }, context_instance=RequestContext(request)) else: selected_choice.votes += 1 selected_choice.save() return HttpResponseRedirect(reverse('polls.views.results', args=(p.id,))) #显示投票结果 def results(request, poll_id): p = get_object_or_404(Poll, pk=poll_id) return render_to_response('results.html', {'poll': p})
在polls下创建templates文件夹,并创建以下三个文件
detail.html
<h1>{{ poll.question }}</h1> {% if error_message %}<p><strong>{{ error_message }}</strong></p>{% endif %} <form action="/polls/{{ poll.id }}/vote/" method="post"> {% csrf_token %} {% for choice in poll.choice_set.all %} <input type="radio" name="choice" id="choice{{ forloop.counter }}" value="{{ choice.id }}" /> <label for="choice{{ forloop.counter }}">{{ choice.choice }}</label><br /> {% endfor %} <input type="submit" value="Vote" /> </form>
index.html
{% if latest_poll_list %} <ul> {% for poll in latest_poll_list %} <li><a href="/polls/{{ poll.id }}/">{{ poll.question }}</a></li> {% endfor %} </ul> {% else %} <p>No polls are available.</p> {% endif %}
results.html
<h1>{{ poll.question }}</h1> <ul> {% for choice in poll.choice_set.all %} <li>{{ choice.choice }} -- {{ choice.votes }} vote{{ choice.votes|pluralize }}</li> {% endfor %} </ul> <a href="/polls/{{ poll.id }}/">Vote again?</a>