Django simple sample

我想写[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 syncdb
Creating tables ...
Creating table auth_permission
Creating table auth_group_permissions
Creating table auth_group
Creating table auth_user_groups
Creating table auth_user_user_permissions
Creating table auth_user
Creating table django_content_type
Creating table django_session
Creating table django_site

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

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

from django import forms
from django.contrib.auth.models import User
from bootstrap_toolkit.widgets import BootstrapDateInput, BootstrapTextInput, BootstrapUneditableInput

class 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 auth
from django.contrib import messages
from django.template.context import RequestContext

from django.forms.formsets import formset_factory
from django.core.paginator import Paginator, PageNotAnInteger, EmptyPage

from bootstrap_toolkit.widgets import BootstrapUneditableInput
from django.contrib.auth.decorators import login_required

from .forms import LoginForm

def 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_required
def 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 models
from django.contrib.auth.models import User

class 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_name

class 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_name

class State(models.Model):
    id = models.AutoField(primary_key=True)
    statename = models.CharField(max_length=20)
    def __unicode__(self):
        return self.statename

class 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.databaseip

class 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 admin
admin.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 admin
from .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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值