django实战2-运维日常维护统计

game app
一、models
1、dbupdate
2、codeupdate
3、dbbackup
4、说明
二、、views
0、index
1、list
1)全文搜索
2)字段完全匹配搜索
3)通过多层表单选筛选 按游戏 状态 时间 [备份增加备份等级] 通过Form实现,非JS模式
2、add [提供python,shell调用接口增加数据,给一个返回状态]
3、getjson [提供对外接口]
4、admin [后台modify]
5、统计功能 各种三种类型 主机数量,状态,备份等级
三、表单
1、游戏类型
2、状态
3、等级
4、类型
四、URL
五、部署

开始
1、models
[root@pxe-svr mysite]# cat game/models.py
# -*- coding: UTF-8 -*-
from django.db import models
from django.contrib import admin

# Create your models here.

class Domain(models.Model):
DomainName = models.CharField(max_length = 36,verbose_name="游戏名")
#根据域名来区分游戏名

class DomainAdmin(admin.ModelAdmin):
list_display = ('DomainName',)

class Status(models.Model):
Status = models.CharField(max_length = 10,verbose_name="服务器状态")
#作为服务器状态,Server可以通过外键访问 s = Server.objects.get(id=50) b.Status.status
def __unicode__(self):
return self.Status

class StatusAdmin(admin.ModelAdmin):
list_display = ('Status',)

class Level(models.Model):
Level = models.CharField(max_length = 10,verbose_name="等级")
def __unicode__(self):
return self.Level

class LevelAdmin(admin.ModelAdmin):
list_display = ('Level',)

class Server(models.Model):
serverName = models.CharField(max_length = 36,verbose_name="服务器名称")
serverStatus = models.ForeignKey(Status)
createtime= models.DateTimeField(auto_now_add=True,verbose_name="创建时间")
remark = models.CharField(max_length=64,verbose_name="备注")
def __unicode__(self):
return self.serverName

class ServerAdmin(admin.ModelAdmin):
list_display = ('serverName','serverStatus','createtime','remark')
list_filter = ('serverName','serverStatus','remark')

class DBUpdate(models.Model):
serverName = models.CharField(max_length = 36,verbose_name="服务器名称")
UpdateStatus = models.ForeignKey(Status)
createtime= models.DateTimeField(auto_now_add=True,verbose_name="创建时间")
remark = models.CharField(max_length=64,verbose_name="备注")
def __unicode__(self):
return self.serverName

class DBUpdateAdmin(admin.ModelAdmin):
list_display = ('serverName','UpdateStatus','createtime','remark')
list_filter = ('serverName','UpdateStatus','remark')

class CodeUpdate(models.Model):
serverName = models.CharField(max_length = 36,verbose_name="服务器名称")
UpdateStatus = models.ForeignKey(Status)
createtime= models.DateTimeField(auto_now_add=True,verbose_name="创建时间")
remark = models.CharField(max_length=64,verbose_name="备注")
def __unicode__(self):
return self.serverName

class CodeUpdateAdmin(admin.ModelAdmin):
list_display = ('serverName','UpdateStatus','createtime','remark')
list_filter = ('serverName','UpdateStatus','remark')

class DBBackup(models.Model):
serverName = models.CharField(max_length = 36,verbose_name="服务器名称")
BackupLevel = models.ForeignKey(Level)
BackupStatus = models.ForeignKey(Status)
createtime= models.DateTimeField(auto_now_add=True,verbose_name="创建时间")
remark = models.CharField(max_length=64,verbose_name="备注")
def __unicode__(self):
return self.serverName

class DBBackupAdmin(admin.ModelAdmin):
list_display = ('serverName','BackupLevel','BackupStatus','createtime','remark')
list_filter = ('serverName','BackupLevel','BackupStatus','remark')

admin.site.register(Domain,DomainAdmin)
admin.site.register(Status,StatusAdmin)
admin.site.register(Level,LevelAdmin)

admin.site.register(Server,ServerAdmin)

admin.site.register(DBUpdate,DBUpdateAdmin)
admin.site.register(CodeUpdate,CodeUpdateAdmin)
admin.site.register(DBBackup,DBBackupAdmin)

./manage.py syncdb

2、form
# vim game/ServerForm.py
# -*- coding: UTF-8 -*-
from django import forms
from game.models import Domain,Status,Level

domains = Domain.objects.all()
DOMAIN_CHOICES = []
for domain in domains:
DOMAIN_CHOICES.append([domain.id, domain.DomainName])

statuses = Status.objects.all()
STATUS_CHOICES = []
for status in statuses:
STATUS_CHOICES.append([status.id,status.Status])

levels = Level.objects.all()
LEVEL_CHOICES = []
for level in levels:
LEVEL_CHOICES.append([level.id,level.Level])

class gamestatusForm(forms.Form):
domainname = forms.ChoiceField(choices = DOMAIN_CHOICES, label= u'选择游戏')
serverstatus = forms.ChoiceField(choices = STATUS_CHOICES, label= u'选择状态')

class statusForm(forms.Form):
domainname = forms.ChoiceField(choices = DOMAIN_CHOICES, label= u'选择游戏')
status = forms.ChoiceField(choices = STATUS_CHOICES, label= u'选择状态')

class dbbackupForm(forms.Form):
domainname = forms.ChoiceField(choices = DOMAIN_CHOICES, label= u'选择游戏')
status = forms.ChoiceField(choices = STATUS_CHOICES, label= u'选择状态')
level = forms.ChoiceField(choices = LEVEL_CHOICES, label= u'选择类型')

3、模版
codeupdate_list.html dbupdate_list.html一样
注意没有搜索到返回的连接<a href = "/dbupdate/list">请返回</a>
dbbackup_list.html有不一样的地方,total需要另外写
{{form.level}}
<td>{{ record.BackupLevel }}</td>
<td>{{ record.BackupStatus }}</td>

注意 DBBackup 增加了一个form 要多一倍的判断
1)list
[root@pxe-svr mysite]# cat game/templates/dbbackup_list.html
{% extends 'base.html' %}
{% block title %} 服务器状态查询 {% endblock %}
{% block content %}
<div class = "waper">
<div class = "header">
<ul id = "nav-global">
<li id = "nav-homepage">
<a href = "/index">首页</a>
</li>
<li id = "nav-login">
<a href = "/admin">登录</a>
</li>
</ul>
</div>
<div class = "search">
<!-- form action="" method="get" class = "search-form" -->
<!-- input type="text" name="q" -->
<!-- input type="submit" value="查询" -->
<!-- /form -->
<form action="" method="get">
<label>游戏名:</label>
{{form.domainname}}
<label>类型:</label>
{{form.level}}
<label>状态:</label>
{{form.status}}
<input type="submit" value="筛选">
</form>

</div>

{% if record_list %}
<div id = "record_list">
<table class = "table_record_list">
<tr>
<th>编号</th>
<th>服务器名</th>
<th>类型</th>
<th>状态</th>
<th>时间</th>
<th>备注</th>
</tr>
{% for record in record_list.object_list %}
<tr>
<td>{{ record.id }}</td>
<td>{{ record.serverName }}</td>
<td>{{ record.BackupLevel }}</td>
<td>{{ record.BackupStatus }}</td>
<td>{{ record.createtime|date:"Y-m-d H:i:s" }}</td>
<td>{{ record.remark }}</td>
</tr>
{% endfor %}
</table>
<div class="pagination">
<span class="step-links">
{% if record_list.has_previous %}
<a href="?page={{ record_list.previous_page_number }}">上一页</a>
{% endif %}

<span class="goback">
{% for p in page_range %}
{% ifequal p books.number %}
<span class="current">{{p}}</span>
{% else %}
<a href="?page={{p}}" title="第{{p}}页">{{p}}</a>
{% endifequal %}
{% endfor %}
</span>

<span class="current">
第 {{ record_list.number }} 页
</span>
<span class="total">
共 {{ record_list.paginator.num_pages }} 页
</span>

{% if record_list.has_next %}
<a href="?page={{ record_list.next_page_number }}">下一页</a>
{% endif %}
</span>
</div>
</div>
{% else %}
<p class="tip">抱歉,没有找到与“<span>{{ query }}</span>”相关的记录</p>
<li id = "nav-login">
<a href = "/dbbackup/list">请返回</a>
</li>
{% endif %}
<div class = "footer">
</div>
</div>
{% endblock %}
2)insert
三个insert都统一为一个模版吧
# cat game/templates/game_insert.html
<html>
<head>
</head>
<body>
{% if error %}
<p style="color: red;">error</p>
{% else %}
<p style="color: red;">ok</p>
{% endif %}
</body>
</html>
>>> DBUpdate(serverName='s2.shaiya.com',UpdateStatus='OK',remark='test1').save()
Traceback (most recent call last):
File "<console>", line 1, in <module>
File "/usr/lib/python2.6/site-packages/Django-1.4.1-py2.6.egg/django/db/models/base.py", line 355, in __init__
setattr(self, field.name, rel_obj)
File "/usr/lib/python2.6/site-packages/Django-1.4.1-py2.6.egg/django/db/models/fields/related.py", line 366, in __set__
self.field.name, self.field.rel.to._meta.object_name))
ValueError: Cannot assign "'OK'": "DBUpdate.UpdateStatus" must be a "Status" instance.
无法插入,因为插入需要一个Status实例
UpdateStatus = models.ForeignKey(Status)
修改插入代码为
ValueError: invalid literal for int() with base 10: 'OK'
DBUpdate(serverName='s2.shaiya.com',UpdateStatus=Status('OK'),remark='test1').save()
mysql> select * from game_dbupdate ;
+----+---------------+-----------------+---------------------+--------+
| id | serverName | UpdateStatus_id | createtime | remark |
+----+---------------+-----------------+---------------------+--------+
| 1 | s1.eve.com | 2 | 2012-10-28 13:37:58 | OK |
| 2 | s2.shaiya.com | 3 | 2012-10-28 13:38:07 | BAD |
+----+---------------+-----------------+---------------------+--------+
mysql> select * from game_status;
+----+--------+
| id | Status |
+----+--------+
| 1 | ALL |
| 2 | OK |
| 3 | BAD |
+----+--------+
>>> Status.objects.get(Status='OK').id
2L
>>> updatestatus=Status.objects.get(Status='OK')
>>> DBUpdate(serverName='s2.shaiya.com',UpdateStatus=updatestatus,remark='test1').save()
解决方法
dbupdatestatus=Status.objects.get(Status=updatestatus)
DBUpdate(serverName=servername,UpdateStatus=dbupdatestatus,remark=remark).save()

4、视图
1)、增加统计
DBUpdate.objects.count()
DBUpdate.objects.filter(serverName='s1.eve.com').count()
>>> status=Status.objects.get(Status='OK')
>>> DBUpdate.objects.filter(UpdateStatus=status).count()
核心代码
def Game_Report(request,template_name):
CodeUpdate_countlist=[]
DBUpdate_countlist=[]
DBBackup_countlist=[]
domains = Domain.objects.all()
statuses = Status.objects.all()
levels = Level.objects.all()
for domain in domains:
if domain.id > 1:
for status in statuses:
if status.id > 1:
dbcount=DBUpdate.objects.filter(serverName__endswith=domain.DomainName,UpdateStatus=status).count()
DBUpdate_dict={'gamename':domain.DomainName,'status':status.Status,'total':dbcount}
DBUpdate_countlist.append(DBUpdate_dict)
codecount=CodeUpdate.objects.filter(serverName__endswith=domain.DomainName,UpdateStatus=status).count()
CodeUpdate_dict={'gamename':domain.DomainName,'status':status.Status,'total':codecount}
CodeUpdate_countlist.append(CodeUpdate_dict)
"""
for level in levels:
if level.id > 1:
DBBackup_countlist.append(DBBackup.objects.filter(serverName__endswith=domain.DomainName,BackupStatus=status,BackupLevel=level).count())
"""
#return {'CodeUpdate_countlist':CodeUpdate_countlist,'DBUpdate_countlist':DBUpdate_countlist,'DBBackup_countlist':DBBackup_countlist}
#return {'CodeUpdate_countlist':CodeUpdate_countlist,'DBUpdate_countlist':DBUpdate_countlist}
return render_to_response(template_name,{'CodeUpdate_countlist':CodeUpdate_countlist,'DBUpdate_countlist':DBUpdate_countlist})

总结:template可以处理字典列表 处理给render_to_response一个字典,字典的Value是列表,列表里有多个字典。

2)增加获取json格式视图
核心代码
def Data_Json(request):
'''return all json data in list if type,type is domain'''
domains = Domain.objects.all()
statuses = Status.objects.all()
levels = Level.objects.all()
domain_list=[]
DBUpdate_list=[]
CodeUpdate_list=[]
DBBackup_list=[]
for domain in domains:
if domain.id > 1:
for status in statuses:
if status.id > 1:
DBUpdate_dict={'gamename':domain.DomainName,'status':status.Status}
DBUpdate_list.append(DBUpdate_dict)
CodeUpdate_dict={'gamename':domain.DomainName,'status':status.Status}
CodeUpdate_list.append(CodeUpdate_dict)
for level in levels:
if level.id > 1:
DBBackup_dict={'gamename':domain.DomainName,'status':status.Status,'level':level.Level}
DBBackup_list.append(DBBackup_dict)
all_dict={'DBUpdate_list':DBUpdate_list,'CodeUpdate_list':CodeUpdate_list,'DBBackup_list':DBBackup_list}
#return all_dict
return HttpResponse(simplejson.dumps(all_dict), mimetype='application/json')
http://192.168.78.250:8080/data/可以得到json格式数据
http://www.bejson.com/ 查看格式
5、URL
urlpatterns += patterns('game.views',
(r'^index/$', direct_to_template, {'template': 'index.html'}),
#(r'^serverstatus_list/$','serverstatus_list',{'template_name': 'serverstatus_list.html'}),
(r'^data/$','Data_Json'),
(r'^report/$','Game_Report',{'template_name': 'report.html'}),
(r'^dbupdate/list/$','dbupdate_list',{'template_name': 'dbupdate_list.html'}),
(r'^dbupdate/add/(?P<servername>[^/]+)/(?P<status>[^/]+)/(?P<remark>[^/]+)/$','DBUpdate_insert',{'template_name': 'game_insert.html'}),
(r'^codeupdate/list/$','codeupdate_list',{'template_name': 'codeupdate_list.html'}),
(r'^codeupdate/add/(?P<servername>[^/]+)/(?P<status>[^/]+)/(?P<remark>[^/]+)/$','CodeUpdate_insert',{'template_name': 'game_insert.html'}),
(r'^dbbackup/list/$','dbbackup_list',{'template_name': 'dbbackup_list.html'}),
(r'^dbbackup/add/(?P<servername>[^/]+)/(?P<level>[^/]+)/(?P<status>[^/]+)/(?P<remark>[^/]+)/$','DBBackup_insert',{'template_name': 'game_insert.html'}),
)

部署程序 不更改目录的情况下
(一) 基本设置
1、关闭Debug模式
2、实现一个404模板
{% extends "base.html" %}

{% block title %}Page not found{% endblock %}

{% block content %}
<h1>Page not found</h1>

<p>Sorry, but the requested page could not be found.</p>
{% endblock %}
3、实现一个500模板
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html lang="en">
<head>
<title>Page unavailable</title>
</head>
<body>
<h1>Page unavailable</h1>

<p>Sorry, but the requested page is unavailable due to a
server hiccup.</p>

<p>Our engineers have been notified, so check back later.</p>
</body>
</html>
(二)用Apache和mod_python来部署Django
1、安装
rpm -ivh ftp://195.220.108.108/linux/epel/6/i386/epel-release-6-7.noarch.rpm
yum -y install mod_python.i686
2、基本配置
#mkdir /data/logs/djlog/
#mkdir /tmp/python/
#chown apache /tmp/python/
全部完整配置
LoadModule python_module modules/mod_python.so
Listen 8080
<VirtualHost *:8080>
DocumentRoot "/data/codedir/mysite"
ServerName pxe-svr.abc.cn
ErrorLog /data/logs/djlog/error_log
CustomLog /data/logs/djlog/access_log common

<Directory "/data/codedir/mysite">
Options Indexes FollowSymLinks
AllowOverride None
Order allow,deny
Allow from all
</Directory>
<Location "/">
SetHandler python-program
PythonHandler django.core.handlers.modpython
PythonPath "['/data/codedir/mysite']+['/data/codedir/mysite/mysite'] + sys.path"
SetEnv DJANGO_SETTINGS_MODULE settings
SetEnv PYTHON_EGG_CACHE /tmp/python/
PythonDebug On
</Location>

<LocationMatch "\.(jpg|gif|png|css|js)$">
SetHandler None
</LocationMatch>
</VirtualHost>
admin的css没有了
[Thu Nov 01 10:03:50 2012] [error] [client 192.168.78.1] File does not exist: /data/codedir/mysite/static, referer: http://192.168.78.250:8080/admin/
这里推荐2个方法:
1). 在你的documentroot目录下创建一个指向admin媒体目录的符号链接。
这个做法的好处就是你的Django本身的文件都在原来的位置上,你可以
svn更新你的django代码等。
2). 或者将admin的媒体文件复制到apache的documentroot目录下面
# pwd
/data/codedir/mysite
# ln -s /usr/lib/python2.6/site-packages/Django-1.4.2-py2.6.egg/django/contrib/admin/static ./static

 

posted on 2012-11-04 17:08  @Jin  阅读(932)  评论(0编辑  收藏  举报

导航