实践:Backbone作前端,Django+Tastypie作后端的简单Web在线聊天室

时间:2022-08-28 14:22:00

一、界面设计:

实践:Backbone作前端,Django+Tastypie作后端的简单Web在线聊天室

二、数据模型设计

id 每个发言都有一个独立的id由tastypie自动生成

content 发言的内容

username 发言者

date 发言时间

三、前端制作

这里没有用到Backbone的Router,因为这里不需要记录hash记录

1.Div+CSS制作静态页面,这里item-template为每一个发言的模版

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<title></title>
<style type="text/css">
ul, li
{
margin
:0px;
padding
:0px;
list-style
:none;
}
body
{
}
#wrapper
{
width
:1000px;
margin
:0px auto;
}
#wrapper .header
{
width
: 100%;
background-color
: rgb(46, 177, 232);
}
#wrapper .content
{
width
: 100%;
}
#wrapper .content .username
{
color
: red;
}
#wrapper .content .time
{
color
: orange;
}
#wrapper .content .item_content
{
color
: blue;
}
#wrapper .content_ul, #wrapper .item
{
background-color
: rgb(237, 237, 237);
padding
: 10px;
}
#wrapper .destroy
{
color
: green;
font-weight
: bold;
cursor
: pointer;
}
#wrapper .footer
{
width
:100%;
float
: left;
background-color
: rgb(46, 177, 232);
padding
: 10px 0px;
}
#wrapper .footer .fl
{
width
:80%;
float
:left;
}
#wrapper .footer .fr
{
width
:20%;
float
:left;
}
#wrapper .footer .fr::after
{
clear
:both;
}
#new_chat
{
width
: 100%;
height
: 80px;
}
#wrapper .footer .fr_up
{
margin-left
: 30px;
margin-bottom
: 10px;
}
#wrapper .footer .fr_down
{
margin-left
: 30px;
}
#nickname
{
width
: 97px;
}
#wrapper .footer .send
{
width
: 150px;
background-color
: green;
display
: block;
text-align
: center;
padding
: 20px;
text-decoration
: none;
}

</style>
</head>
<body>
<div id="wrapper">
<div class="header">
[ Chat Room Beta 1.0 ]
</div>
<div class="content">
<ul class="content_ul">
</ul>
</div>
<div class="footer">
<div class="fl"><textarea id="new_chat" autofocus></textarea></div>
<div class="fr">
<div class="fr_up">
呢称:
<input id="nickname" type="text"/>
</div>
<div class="fr_down">
<button class="send" id="send">发送消息</button>
</div>
</div>
</div>
</div>
<script type="text/template" id="item-template">
<span class="username"><%=username %></span> : <span class="time"><%=date %></span> <a class="destroy">X</a><br />
<span class="item_content"><%=content %></span>
</script>

<script src="/static/chatroom/js/vendor/jquery.js"></script>
<script src="/static/chatroom/js/vendor/underscore.js"></script>
<script src="/static/chatroom/js/vendor/backbone.js"></script>
<script src="/static/chatroom/js/models.js"></script>
<script src="/static/chatroom/js/views.js"></script>
</body>
</html>

2.Backbone Models 文件,为了方便,这里把model与collection都放到同一文件了,\static\chatroom\js\models.js

var Chat = Backbone.Model.extend({

urlRoot:
'/api/v1/chat/',

defualts: {
content:
'',
username:
'',
date:
''
},

clear:
function () {
this.destroy();
}
});

var ChatList = Backbone.Collection.extend({

url:
'/api/v1/chat/',
parse:
function (response) {
return response.objects;
},

model: Chat

});

3.Backbone Views文件,为了方便,参照todoMVC把视图划分为两个,一个是ChatView用于每个发言,一个为AppView用于整体处理,这里把ChatView与AppView都放到同一文件了,\static\chatroom\js\views.js

var chatList = new ChatList;//New 一个Collection下面会用到
var ChatView = Backbone.View.extend({
tagName:
'li',
className:
'item',

template: _.template($(
'#item-template').html()),
events: {
'click .destroy': 'clear'
},

initialize:
function () {
_.bindAll(
this, 'render', 'remove');
this.model.bind('change', this.render);
this.model.bind('destroy', this.remove);
},

render:
function () {
$(
this.el).html(this.template(this.model.toJSON()));
This
= $(this.el).find('.time');
This.text(This.text().split(
'.')[0].replace('T',' '));//注意这里tastypie提供的时间格式为:2015-03-01T23:52:26.854388 所以要对时间进行格式化一下
return this;
},

clear:
function () {
this.model.clear();
}
});

var AppView = Backbone.View.extend({
el: $(
'#wrapper'),

events: {
"click #send": "say"
},

initialize:
function () {
_.bindAll(
this, 'addOne', 'addAll');
this.nickname = this.$('#nickname');
this.textarea = this.$("#new_chat");

chatList.bind(
'add', this.addOne);
chatList.bind(
'reset', this.addAll);
chatList.fetch();
setInterval(
function () {
chatList.fetch({ add:
true });
},
5000);
},

addOne:
function (chat) {
//页面所有的数据都来源于server端,如果不是server端的数据,不应添加到页面上
if (!chat.isNew()) {
var view = new ChatView({ model: chat });
this.$(".content_ul").append(view.render().el);
$(
'.content').scrollTop($(".content_ul").height() + 50);
}
},

addAll:
function () {
chatList.each(
this.addOne);
},

say:
function (event) {
chatList.create(
this.newAttributes());
//为了满足IE和FF以及chrome
this.textarea.text('');
this.textarea.val('');
this.textarea.html('');

},


newAttributes:
function () {

var content = this.textarea.val();
if (content == '') {
content
= this.textarea.text();
}

return {
content: content,
username:
this.nickname.val()
};
}
});

var appView = new AppView;//启动程序

到这里前端代码已经完成。

四、后端处理

这里用Django自带的SQLite作后台数据库

1.Django Model文件-D:\project\mysite\ChatRoom\models.py

from django.db import models

class Chat(models.Model):
content
= models.CharField(max_length=1024)
username
= models.CharField(max_length=1024)
date
= models.DateTimeField(auto_now_add=True)

2.配置TastyPie API文件-D:\project\mysite\ChatRoom\api\resources.py

from tastypie.authorization import Authorization
from tastypie import fields
from tastypie.resources import ModelResource
from ChatRoom.models import Chat

class ChatResource(ModelResource):
class Meta:
queryset
= Chat.objects.all()
resource_name
= 'chat'
authorization
= Authorization()
fields
=['id','username','content','date']

3.Restfull API的Url文件配置-D:\project\mysite\mysite\urls.py

from django.conf.urls import patterns, include, url
from tastypie.api import Api
from ChatRoom.api.resources import ChatResource

v1_api
= Api(api_name='v1')
v1_api.register(ChatResource())

urlpatterns
= patterns('',
url(r
'^admin/', include(admin.site.urls)),
url(r
'^api/', include(v1_api.urls)),
)

把数据库导好及配置好Tastypie,运行测试,可以正常留言!

 

 

参考引用

http://www.the5fire.com/

https://github.com/tastejs/todomvc