Django simple sample

来源:互联网 发布:施工网络进度计划 编辑:程序博客网 时间:2024/05/24 05:29

我想写[Django实战]这系列的文章是因为我最近在开发一个数据库脚本发布系统,该系统只限于公司内部使用,它的功能非常简单明了:开发人员通过该系统提交SQL语句,DBA审核后执行,并将结果反馈给开发人员。

当然,开发这种小系统方法很多,我选择的是Django+Bootstrap,Web框架选择Django是因为我对Python语言比较熟,平时经常用它写一些自动化脚本;前端框架选择Bootstrap是因为我很喜欢它那种小清新的界面风格。
这一系列的实战文章会详细记录我开发这个系统的过程,包括设计、源码等,因为我也是第一次使用Django,所以难免会有纰漏和错误,请大家多多指教。
所谓“工欲善其事,必先利其器”,下面介绍如何安装Django+Bootstrap。
 
Django 安装
在安装Django之前,系统上必须已经安装了Python,至于如何安装Python,这里就不多讲了,有兴趣的可以参考下我之前写的《[Python]安装及环境配置》,我选择的Python版本是2.7.3,这里建议大家不要使用Python 3,因为Python 3做了比较大的改动,目前还不太稳定,最重要的是很多API都改了,可能不兼容旧版本。
安装好Python之后,建议安装easy_install,这样直接使用命令easy_install django即可下载最新版本,非常方便。
当然也可以采用源码安装,首先到Django官网下载tar.gz文件,然后:
tar xzvf Django-1.5.2.tar.gz
cd Django-1.5.2
sudo python setup.py install
 
django-bootstrap-toolkit 安装
关于Bootstrap的界面风格大家可以去Bootstrap的首页去看下,我个人很喜欢这种小清新的风格,
dyve大牛开发了开源软件包django-bootstrap-toolkit,大家可以去github下载,链接地址是https://github.com/dyve/django-bootstrap-toolkit
通过该软件包,我们可以把Django和Bootstrap无缝结合起来,非常方便。这里顺便吐槽下百度,当我在百度里搜django bootstrap时,死活搜不到,但是用google搜第一个就是它,所以和技术相关的东西大家还是用google吧。
 
创建Django项目
Django安装成功后,就可以使用django-admin.py创建项目:
[python] view plaincopyprint?
# django-admin.py startproject dbrelease  
dbrelease是我为这个项目起的名字。
项目创建成功后,我们还要创建应用程序:
[python] view plaincopyprint?
# python manage.py startapp dbrelease_app  
然后再settings.py的INSTALLED_APPS添加'dbrelease_app'应用程序
现在我们运行一下Web服务器:
[python] view plaincopyprint?
# python manage.py runserver 192.168.1.16:8000  
在浏览器里输入http://192.168.1.16:8000/就可以看到Django淡蓝色的欢迎界面,因为现在还是一个空项目,除了欢迎界面其它的什么都没有,接下来的全部工作就是丰富页面内容。
 
为了在新创建的Django项目中能使用bootstrap,我们需要把文件夹bootstrap_toolkit拷贝到项目主文件夹下,并在settings.py文件中的INSTALLED_APPS里添加'bootstrap_toolkit'应用程序。

前两篇讲述了Django的理论,从这篇开始,我们真正进入Django实战部分,今天先从用户认证开始。

当大家平时打开一个网站时,第一步一般做什么?我猜大部分是先登录吧,所以我们就从用户认证开始。


打开用户认证

Django本身已经提供了用户认证模块,所以我们要做的事很简单,就是在它的基础上添加一些定制化的东西。默认情况下,Django的用户认证模块是打开的,可以通过以下步骤确认用户模块是否打开(在settings.py文件里):

1、确保 MIDDLEWARE_CLASSES 中包含 'django.contrib.sessions.middleware.SessionMiddleware'。
2、确认 INSTALLED_APPS 中有 'django.contrib.sessions' 
3、将 'django.contrib.auth' 放在你的 INSTALLED_APPS 设置中,然后运行 manage.py syncdb以创建对应的数据库表。
4、确认 SessionMiddleware 后面的 MIDDLEWARE_CLASSES 设置中包含 'django.contrib.auth.middleware.AuthenticationMiddleware'。


数据库配置

用户认证系统必然离不开数据库,因为用户信息需要保存在数据库里,Django自带的用户认证系统也不例外。在使用它之前,必须配置数据库,Django支持大部分的主流数据库,这里我采用的是Oracle数据库,首先需要安装cx_Oracle模块,Django必须通过它才能访问Oracle数据库。至于如何安装cx_Oracle模块,这里就不讲了,具体查看官方文档。

接着在Oracle中创建一个用户,我们Django项目创建的所有表都建在该用户下,因此需要相应的权限:

SQL> create user dbrelease identified by * default tablespace dbrelease;SQL> grant resource,create session,unlimited tablespace to dbrelease;
然后在settings.py中的Databases属性里设置django连接oracle:

DATABASES = {    'default': {        'ENGINE': 'django.db.backends.oracle',         'NAME': 'lxdbtest',                             'USER': 'dbrelease',        'PASSWORD': '*',        'HOST': '192.168.1.16',                              'PORT': '1521',                          }}
注意:上面的NAME是指Oracle的instance_name

好了,下面验证是否可以成功连接Oracle:

进入Django项目的主目录,运行python manage.py shell进入交互命令行,然后输入:

>>> from django.db import connection>>> cursor = connection.cursor()
如果没有报错,说明已经配置成功。

最后执行syncdb语句,从以下输出中我们可以发现,用户认证系统默认在数据库里创建了以下表:

# python manage.py syncdbCreating tables ...Creating table auth_permissionCreating table auth_group_permissionsCreating table auth_groupCreating table auth_user_groupsCreating table auth_user_user_permissionsCreating table auth_userCreating table django_content_typeCreating table django_sessionCreating table django_site

上一篇中,我们已经打开了Django自带的用户认证模块,并配置了数据库连接,创建了相应的表,本篇我们将在Django自带的用户认证的基础上,实现自己个性化的用户登录和注销模块。

首先,我们自己定义一个用户登录表单(forms.py):

from django import formsfrom django.contrib.auth.models import Userfrom bootstrap_toolkit.widgets import BootstrapDateInput, BootstrapTextInput, BootstrapUneditableInputclass LoginForm(forms.Form):    username = forms.CharField(        required=True,        label=u"用户名",        error_messages={'required': '请输入用户名'},        widget=forms.TextInput(            attrs={                'placeholder':u"用户名",            }        ),    )        password = forms.CharField(        required=True,        label=u"密码",        error_messages={'required': u'请输入密码'},        widget=forms.PasswordInput(            attrs={                'placeholder':u"密码",            }        ),    )       def clean(self):        if not self.is_valid():            raise forms.ValidationError(u"用户名和密码为必填项")        else:            cleaned_data = super(LoginForm, self).clean() 
我们定义的用户登录表单有两个域username和password,这两个域都为必填项。

接下来,我们定义用户登录视图(views.py),在该视图里实例化之前定义的用户登录表单

from django.shortcuts import render_to_response,render,get_object_or_404  from django.http import HttpResponse, HttpResponseRedirect  from django.contrib.auth.models import User  from django.contrib import authfrom django.contrib import messagesfrom django.template.context import RequestContextfrom django.forms.formsets import formset_factoryfrom django.core.paginator import Paginator, PageNotAnInteger, EmptyPagefrom bootstrap_toolkit.widgets import BootstrapUneditableInputfrom django.contrib.auth.decorators import login_requiredfrom .forms import LoginFormdef login(request):    if request.method == 'GET':        form = LoginForm()        return render_to_response('login.html', RequestContext(request, {'form': form,}))    else:        form = LoginForm(request.POST)        if form.is_valid():            username = request.POST.get('username', '')            password = request.POST.get('password', '')            user = auth.authenticate(username=username, password=password)            if user is not None and user.is_active:                auth.login(request, user)                return render_to_response('index.html', RequestContext(request))            else:                return render_to_response('login.html', RequestContext(request, {'form': form,'password_is_wrong':True}))        else:            return render_to_response('login.html', RequestContext(request, {'form': form,}))

该视图实例化了之前定义的LoginForm,它的主要业务逻辑是:

1. 判断必填项用户名和密码是否为空,如果为空,提示"用户名和密码为必填项”的错误信息

2. 判断用户名和密码是否正确,如果错误,提示“用户名或密码错误"的错误信息

3. 登陆成功后,进入主页(index.html)

其中,登录页面的模板(login.html)定义如下:

<!DOCTYPE html>{% load bootstrap_toolkit %}{% load url from future %}<html lang="en"><head>    <meta charset="utf-8">    <title>数据库脚本发布系统</title>    <meta name="description" content="">    <meta name="author" content="朱显杰">    {% bootstrap_stylesheet_tag %}    {% bootstrap_stylesheet_tag "responsive" %}    <style type="text/css">        body {            padding-top: 60px;        }    </style>    <!--[if lt IE 9]>    <script src="//html5shim.googlecode.com/svn/trunk/html5.js"></script>    <![endif]-->    <script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script>    {% bootstrap_javascript_tag %}    {% block extra_head %}{% endblock %}</head><body>    {% if password_is_wrong %}        <div class="alert alert-error">            <button type="button" class="close" data-dismiss="alert">×</button>            <h4>错误!</h4>用户名或密码错误        </div>    {% endif %}        <div class="well">        <h1>数据库脚本发布系统</h1>        <p> </p>        <form class="form-horizontal" action="" method="post">            {% csrf_token %}            {{ form|as_bootstrap:"horizontal" }}            <p class="form-actions">                <input type="submit" value="登录" class="btn btn-primary">                <a href="/contactme/"><input type="button" value="忘记密码" class="btn btn-danger"></a>                <a href="/contactme/"><input type="button" value="新员工?" class="btn btn-success"></a>            </p>        </form>    </div></body></html>

最后还需要在urls.py里添加:

    (r'^accounts/login/$',  'dbrelease_app.views.login'),

最终的效果如下:

1)当在浏览器里输入http://192.168.1.16:8000/accounts/login/,出现如下登陆界面:

Django实战 第4篇  用户认证用户登录与注销

2)当用户名或密码为空时,提示”用户名和密码为必填项",如下所示:

Django实战 第4篇  用户认证用户登录与注销

3)当用户名或密码错误时,提示“用户名或密码错误",如下所示:

Django实战 第4篇  用户认证用户登录与注销

4)如果用户名和密码都正确,进入主页(index.html)。


既然有login,当然要有logout,logout比较简单,直接调用Django自带用户认证系统的logout,然后返回登录界面,具体如下(views.py):

@login_requireddef logout(request):    auth.logout(request)    return HttpResponseRedirect("/accounts/login/")

上面@login[email protected]�图,否则将自动重定向至登录页面。

urls.py里添加:

(r'^accounts/logout/$', 'dbrelease_app.views.logout'),

前面我们实现了用户认证模块,在该模块里其实已经涉及到模块(ORM),但由于是Django自带的,大部分它都已经帮我们处理好,对于我们来说是透明的,本篇,我们将自己定义模型。

在Web开发中,我习惯从数据库层面开始,一方面是因为我本身是做DBA的,对数据库比较了解;另一部分也是因为相比于模板和视图来说,模型从设计之初基本已确定,不会有大的改动。

我们的模型models.py定义如下:

from django.db import modelsfrom django.contrib.auth.models import Userclass Manager(models.Model):    id = models.AutoField(primary_key=True)    username = models.CharField(max_length=30)    first_name = models.CharField(max_length=30)    last_name = models.CharField(max_length=30)    email = models.EmailField(max_length=70)    def __unicode__(self):        return self.last_name + self.first_nameclass Dba(models.Model):    id = models.AutoField(primary_key=True)    username = models.CharField(max_length=30)    first_name = models.CharField(max_length=30)    last_name = models.CharField(max_length=30)    email = models.EmailField(max_length=70)    def __unicode__(self):        return self.last_name + self.first_nameclass State(models.Model):    id = models.AutoField(primary_key=True)    statename = models.CharField(max_length=20)    def __unicode__(self):        return self.statenameclass Database(models.Model):    id = models.AutoField(primary_key=True)    databasename = models.CharField(max_length=30)    databaseip = models.CharField(max_length=30)    def __unicode__(self):        return self.databasename + ' - ' + self.databaseipclass Task(models.Model):    id = models.AutoField(primary_key=True)    creater = models.ForeignKey(User)    manager = models.ForeignKey(Manager)    dba = models.ForeignKey(Dba)    state = models.ForeignKey(State)    databases = models.ManyToManyField(Database)    sql = models.CharField(max_length=2000,blank=True,null=True)    desc = models.CharField(max_length=2000,blank=True, null=True)    createdtime = models.DateTimeField()    lastupdatedtime = models.DateTimeField(blank=True,null=True)    dbacomment = models.CharField(max_length=2000,blank=True,null=True)    attachment = models.FileField(upload_to='tasks',blank=True,null=True)    def __unicode__(self):        return str(self.id)

其中最核心的表是最后一张Task,在业务逻辑上代表开发人员提交给DBA的一个数据库更改请求,其它所有表都是围绕这个表创建的:Manager表是Task.manager的外键,Dba表是Task.dba的外键,State表是Task.state的外键,其中比较特殊的是Task.databases和Database表是多对多的关系。还有一点要注意的是,Task.creater是Django自带的用户表auth_user的外键。

以上models.py定义了ORM关系,但当前这些表只存在models.py中,在数据库中还不存在,我们需要通过以下步骤同步数据库:

首先,通过以下语句验证models.py定义模型的正确性:

python manage.py validate
如果上面没有错误,就可以执行如下语句同步数据库了(在同步之前,一定要先确认settings.py中DATABASES属性已正确配置,具体看第3篇):

python manage.py syncdb
如果你想知道syncdb究竟在数据库里做了什么,可以执行如下语句获得DDL:

python manage.py sqlall app_name
至此,模型已经创建成功,之后我们就可以在Django中自由的操纵数据库了。

在上一篇中,我们自己定义了数据库模型(models.py),并已同步至数据库中,那么如何插入、更新、删除表中数据呢?方法有很多,比如直接写SQL语句在数据库层面插入或调用模型的API,但这两种方法都需要写代码实现,可不可以有更直观页面操作呢?答案当然是肯定的,这就是Django自带的Admin模块,本篇主要讲述它。

首先,我们需要通过以下步骤开启Admin模块:

第一步:对settings.py做如下修改:

1)保证INSTALLED_APPS中包含'django.contrib.auth','django.contrib.contenttypes'和'django.contrib.sessions'(因为我们之前已经使用了Django自动的用户认证系统,因此这三个包应该就在开启的状态)

2)在INSTALLED_APPS中把'django.contrib.admin'和'django.contrib.admindocs'的注释去掉

3)确保MIDDLEWARE_CLASSES 包含'django.middleware.common.CommonMiddleware' 、'django.contrib.sessions.middleware.SessionMiddleware' 和'django.contrib.auth.middleware.AuthenticationMiddleware'

第二步:运行 python manage.py syncdb 。这一步将生成管理界面使用的额外数据库表

第三步:将admin访问配置在URLconf(记住,在urls.py中). 默认情况下,命令django-admin.py startproject生成的文件urls.py是将Django admin的路径注释掉的,你所要做的就是取消注释。如下所示:

# Uncomment the next two lines to enable the admin:from django.contrib import adminadmin.autodiscover()urlpatterns = patterns('',    # Examples:    # url(r'^$', 'dbrelease.views.home', name='home'),    # url(r'^dbrelease/', include('dbrelease.foo.urls')),    # Uncomment the admin/doc line below to enable admin documentation:    url(r'^admin/doc/', include('django.contrib.admindocs.urls')),    # Uncomment the next line to enable the admin:    url(r'^admin/', include(admin.site.urls)),...)

第四步:创建admin.py文件,内容如下:

from django.contrib import adminfrom .models import *admin.site.register(Manager)admin.site.register(Dba)admin.site.register(State)admin.site.register(Database)admin.site.register(Task)

当这一切都配置完毕之后,在浏览器中输入http://192.168.1.16:8000/admin/,登陆成功后就可以使用Admin管理工具了,界面如下:

Django实战 第7篇  Admin管理工具

从以上页面我们发现,除了我们自己定义的模型(Dbrelease_app下的表)外,还有我们之前讲过的Django自带的用户认证模块(Auth)和(Sites)。






1.创建一个项目

  1. django-admin.py startproject myweb

项目里有一下几个目录

  1. myweb/
  2. ├── manage.py     #django自带的服务器管理
  3. └── myweb
  4.     ├── __init__.py   #表明这是一个包结构的,这是一个模块
  5.     ├── settings.py #包含项目的所有配置参数
  6.     ├── urls.py        #URL根配置
  7.     └── wsgi.py       #内置runserver命令的WSGI应用配置

2.更改项目里的基本配置
settings.py

  1. vim myweb/myweb/settings.py
  2. TIME_ZONE = 'Asia/Shanghai'        #设置时区
  3. LANGUAGE_CODE = 'zh-cn'            #设置语言类型
  4. INSTALLED_APPS = (
  5.     'django.contrib.admin',
  6.     'django.contrib.auth',
  7.     'django.contrib.contenttypes',
  8.     'django.contrib.sessions',
  9.     'django.contrib.messages',
  10.     'django.contrib.staticfiles',
  11.     'blog',                                         #增加一个自己的app
  12. )

urls.py

  1. vim myweb/myweb/urls.py
  2. from django.conf.urls import patterns, include, url
  3. from django.contrib import admin
  4. urlpatterns = patterns('',
  5.     # Examples:
  6.     # url(r'^$', 'myweb.views.home', name='home'),
  7.     # url(r'^blog/', include('blog.urls')),
  8.     url(r'^admin/', include(admin.site.urls)),
  9.         url(r'^blog/index/$','blog.views.index'),    #增加这句,表明访问blog/index的时候,调用blog中views里的index方法
  10. )

3.创建blog app

  1. cd myweb
  2. django-admin.py startapps blog    #blog要与settings里面添加的blog要保持一致

blog的目录结构

  1. blog
  2. ├── admin.py
  3. ├── __init__.py
  4. ├── migrations
  5. │   └── __init__.py
  6. ├── models.py
  7. ├── tests.py
  8. └── views.py

4.访问实例
修改blog里的views.py

  1. vim blog/views.py
  2. from django.http import HttpResponse
  3. def index(req):
  4.         return HttpResponse('<h1>hello</h1>')

5.运行manage.py

  1. python manage.py migrate    #如果提示未迁移,则运行这个命令,会有提示
  2. python manage.py runserver


0 0