笔记一 10课
1.视图中的变量在html中展示
A.在视图中定义youPorn变量以及info_data字典
def index(request):
name_info = {
'name':'SanJin',
'age': 21,
'hobbie': "show",
'job': "stripper"
}
#return render(request,'index.html',{'your':"gaoguodeng learn python"})
return render(request, 'index.html', {
'youPorn': "SanJin Is on the show now!",
'info_data': name_info
})
B. 在html文件中引用。双大括号里面带变量名即可,如: `info_data` `youPorn`
2.django 的if 判断
{% if k == "job" %}
{{ k }}::{{ v }}
{% else %}
{{ k }}::{{ v }}
{% endif %}
3. django 的for 循环,也就是在{% python命令 %}
如:
{% for k,v in info_data.items %}
{{ k }}::{{ v }}
{% endfor %}
4.django 应用模版
A.在你的html中引用你想引用的html文件。这是全部被引用(继承)
{% extends 'index.html' %}
B.在你的html文件中引用你想应用的html文件,但是html文件中有部分内容不希望被引用或想被替换(部分引用或部分继承,和部分替换。)
B1.在希望引用的html文件模版中,用下面内容把你不希望被引用或想被替换的内容扩起来。
{% block page-contont %}
...
... {这里面的就是你不想被引用的内容或想替换的内容}
...
{% endblock %}
B2.如果你想替换的上面内容,那就需要用下面命令
{% extends 'index.html' %}
{% block page-contont %}
这里编写你希望替换后的内容(如果不写内容,即替换为空的,也就是不引用上面这里部分内容)
{% endblock %}
笔记二 11课
一.添加静态资源目录
STATIC_URL = '/static/'
STATICFILES_DIRS =[
os.path.join(BASE_DIR,'statics'),
]
二.学习django request 对象
http://python.usyiyi.cn/django/ref/request-response.html
三.动态获取url匹配
1.在urls.py中的url匹配条目中加入name='xxx' 变量
如下面的首页,在后面加: name='index'
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^$', views.index,name='index'),
url(r'^host/$', views.host, name='host'),
url(r'^asset/$', views.asset, name='asset'),
url(r'^audit/$', views.audit, name='audit'),
]
2.在对应的html文件中直接应用url条目的变量即可。
index.html文件中的用法,如下
上面的首页,本应该写为:
主机
现在仅仅用{% url 'host' %}即可代替,日后哪url中的host条目改变了,
这里的html用不需要改变
三.django中models中可选的参数
system_type_choices = {
('linux',"LINUX"),
('win',"Windows"),
}
system_type = models.CharField(max_length=32,choices=system_type_choices)
1.导入模版
{% extends 'index.html' %}
{% block left-sidebar %}
aaa
{% endblock %}
{% block right-sidebar %}
host
{% endblock %}
2.django获取访问的路径
{{ request.path }}
3.切换导航栏高亮
4.url 别名url
name 的值不变,无论前面的正则如何改变,在页面中调用url也不用改
urlpatterns = [
url(r'^admin/', include(admin.site.urls)),
url(r'^$', views.index),
url(r'^host/$', views.host,name='host'),
url(r'^asset/$', views.asset,name='asset'),
url(r'^audit/$', views.audit,name='audit'),
]
5.
模型class ---> 表
字段(属性) ---> 列
方法 ---> 操作数据库
6.重写django的用户
from django.contrib.auth.models import User ##导入django自带的用户表
class UserProfile(models.Model):
user = models.OneToOneField(User) ## 这里用的是一对一关心,把这里的用户关联到django自带的用户
name = models.CharField(max_length=64,unique=True)
##下面的就是扩展的字段
host_groups = models.ManyToManyField('HostGroup',blank=True,null=True) ##用户可以不属于任何一个组
hosts = models.ManyToManyField('Host',blank=True,null=True) ##用户可以不属于任何一个主机
def __unicode__(self):
return self.name
7.django使用mysql数据库
第一步:在mysql数据库中数据对于的库:
create database django01 character set utf8;
第二步:在setting 配置文件中引用这个数据库
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql', # 设置为mysql数据库
'NAME': 'django01', # mysql数据库名
'USER': 'root', # mysql用户名,留空则默认为当前linux用户名
'PASSWORD': 'wdzj@2015', # mysql密码
'HOST': '140.206.51.154', # 留空默认为localhost
'PORT': '1205', # 留空默认为3306端口
}
}
现在Django知道要包含polls应用。 让我们运行另外一个命令:
python manage.py makemigrations polls
python manage.py sqlmigrate polls 0001
运行python manage.py makemigrations ,为这些修改创建迁移文件
运行python manage.py migrate ,将这些改变更新到数据库中。
desc app01_host; #查看app01_host 的表结构
show create table app01_host; ##查看创建app01_host表语句
###########
8.相关表说名
mysql> show tables;
+-------------------------------+
| Tables_in_django1 |
+-------------------------------+
| app01_host |
| app01_host_groups | //这个表是app01_host和app01_hostgroup之间的关联表
| app01_hostgroup |
| app01_idc |
| app01_userprofile |
| app01_userprofile_host_groups | // 这个也是关联变
| app01_userprofile_hosts |
| auth_group |
| auth_group_permissions |
| auth_permission |
| auth_user |
| auth_user_groups |
| auth_user_user_permissions |
| django_admin_log |
| django_content_type |
| django_migrations |
| django_session |
+-------------------------------+
17 rows in set (0.01 sec)
上面的表中,app01是应用的名称,在models中的每个类都会生成一个相应的表,表名就是
应用名称加上_类名,如上面的app01_host表,以及一些关联表,如app01_host_groups
django表之间的关联就是通过中间的一个关联表进行关联的
9.把models.py中创建的表,在web中显示出来
在app01/admin.py 中增加下面内容
import models
from django.contrib import admin
admin.site.register(models.Host)
admin.site.register(models.HostGroup)
admin.site.register(models.IDC)
admin.site.register(models.UserProfile)
admin.site.register(models.IDC)
10.进入django的管理后台
http://0.0.0.0:8000/admin/
11.创建一个django后台超级用户
python manage.py createsuperuser
Lvnian:s10day11_1 root# python manage.py createsuperuser
System check identified some issues:
WARNINGS:
app01.UserProfile.host_groups: (fields.W340) null has no effect on ManyToManyField.
app01.UserProfile.hosts: (fields.W340) null has no effect on ManyToManyField.
Username (leave blank to use 'root'): root
Email address:
Password:
Password (again):
Superuser created successfully.
Lvnian:s10day11_1 root#
9.
def __unicode__(self):
return self.name
10.跨越{% csrf_token %}
当你用post方法提交表单内容时,需要{% csrf_token %}这个
// 这个value就是令牌
print request.POST ##得到的内容
11.创建一条hosts记录:
>>> models.Host.objects.create(
... hostname='gaogdtest',
... ip_addr='10.0.0.112',
... port = 34,
... system_type='linux',
... idc_id = 1 , ## 这个本应该是 idc = models.m
... online_date=datetime.datetime.now(),
... )
/Library/Python/2.7/site-packages/django/db/models/fields/__init__.py:1430: RuntimeWarning: DateTimeField Host.online_date received a naive datetime (2016-09-29 00:00:14.418823) while time zone support is active.
RuntimeWarning)
>>>
idc的正常关联方法
>>> models.Host.objects.create(
... hostname='gaogdtest01',
... ip_addr='10.0.10.112',
... port = 23,
... system_type='linux',
... idc = models.IDC.objects.get(id=1),
... online_date=datetime.datetime.now(),
... )
/Library/Python/2.7/site-packages/django/db/models/fields/__init__.py:1430: RuntimeWarning: DateTimeField Host.online_date received a naive datetime (2016-09-29 00:05:03.826884) while time zone support is active.
RuntimeWarning)
>>>
批量给主机添加组:h.groups.add(*[i.id for i in all_groups])
>>> all_groups=models.HostGroup.objects.all()
>>> [i.id for i in all_groups]
[1L, 2L]
>>> h=models.Host.objects.get(id=1)
>>> h.groups.add(*[i.id for i in all_groups])
>>>
>>> h.groups.remove( for i in all_groups])
###创建host条目的另外一种方法
h=models.Host(
hostname='gaogdtest02',
ip_addr='10.0.10.13',
port = 23,
system_type='linux',
idc = models.IDC.objects.get(id=1),
online_date=datetime.datetime.now(),
)
h.save()
h.id
>>> h=models.Host(
... hostname='gaogdtest02',
... ip_addr='10.0.10.13',
... port = 23,
... system_type='linux',
... idc = models.IDC.objects.get(id=1),
... online_date=datetime.datetime.now(),
... )
>>>
>>> h.save()
/Library/Python/2.7/site-packages/django/db/models/fields/__init__.py:1430: RuntimeWarning: DateTimeField Host.online_date received a naive datetime (2016-09-29 00:22:24.872968) while time zone support is active.
RuntimeWarning)
>>> h.id
5L
>>> h.groups.add(*[i.id for i in all_groups])
>>>
12.修改hostname
>>> h.hostname
'gaogdtest02'
>>> h.hostname='gaogd02'
>>> h.save()
>>>
批量修改port
>>> models.Host.objects.filter().update(port=22)
5L
>>>
删除
h.delete()
13.调用django的认证系统
from django.contrib.auth import authenticate
14.验证用户是否登陆:
{% if request.user.is_authenticated %}
{{ request.user }}
{% else %}
登录
{% endif %}
{{ request.user.userprofile.name }} //显示全名
{{ request.user }} //显示用户名
15.多表查询
{{ request.user.userprofile.hosts.select_related }} // 通过用户,找到主机。注意登陆用户必须要有相关的主机才有内容出来
循环这个组
{% for group in request.user.userprofile.host_groups.select_related %}
{{ group.name }}
{% endfor %}
循环这个组,找到每个组里面的主机
{% for group in request.user.userprofile.host_groups.select_related %}
{{ group.name }}
{{ group.host_set.select_related }}
{% endfor %}
这个asset的内容
{{ request.user.userprofile.hosts.select_related }}
{% for group in request.user.userprofile.host_groups.select_related %}
-
{{ group.name }}
{% for host in group.host_set.select_related %}
-
{{ host.hostname }} --->{{ host.ip_addr }}
{% endfor %}
{% endfor %}
#############
[]
db
ubuntu --->192.168.10.11
AlexTest --->10.0.0.5
web集群
windows --->192.168.10.12
localhost --->192.168.9.33
AlexTest --->10.0.0.5
gaogd --->10.0.0.6
16.用户登陆
from django.contrib.auth import authenticate,login,logout
login(request,user) ##这才是真正的登陆
17.用户退出
from django.contrib.auth import authenticate,login,logout
logout(request)
18.判断如果用户没有登陆就不让访问
a.导入模版
from django.contrib.auth.decorators import login_required
b.在每个需要认证页面的views 的函数前加入@login_required
如:
@login_required
def host(request)
return render(request,'host.html')
19.models.py 说明:
#!/usr/bin/python
# -*- coding: utf-8 -*-
__author__ = 'gaogd'
from django.contrib.auth.models import User
from django.db import models
# Create your models here.
class Host(models.Model):
hostname = models.CharField(max_length=64,unique=True)
ip_addr = models.GenericIPAddressField(unique=True)
port = models.IntegerField(default=22)
system_type_choices = {
('linux',"LINUX"),
('win',"Windows"),
}
system_type = models.CharField(max_length=32,choices=system_type_choices) ##这是一个选择框,选择的内容是system_type_choices中定义的
idc = models.ForeignKey('IDC') ##一对多关心。每创建一个主机,必须关联到一个IDC机房,同时,如果创建一个idc机房的时候,可以选择多台主机
groups = models.ManyToManyField('HostGroup') ##这里的多对多,是说明创建主机的时候,你可以选择多个组,同时,创建一个组的时候,可以选择多个主机
enabled = models.BooleanField(default=True) ##判断主机是否上线(上线,下线),默认上线
online_date = models.DateTimeField()##什么时候上线的
create_date = models.DateTimeField(auto_now_add=True)##什么时候创建or添加这台服务器的,auto_now_add=True代表不用我写具体什么时候创建的,在创建这台服务器的时候,他自动生成
def __unicode__(self):
return self.hostname
class IDC(models.Model):
name = models.CharField(max_length=64, unique=True)
def __unicode__(self):
return self.name
class HostGroup(models.Model):
name = models.CharField(max_length=64,unique=True)
def __unicode__(self):
return self.name
class UserProfile(models.Model):
user = models.OneToOneField(User) ## 这里用的是一对一关心,把这里的用户关联到django自带的用户
name = models.CharField(max_length=64,unique=True)
host_groups = models.ManyToManyField('HostGroup',blank=True,null=True) ##用户可以不属于任何一个组
hosts = models.ManyToManyField('Host',blank=True,null=True) ##用户可以不属于任何一个主机
def __unicode__(self):
return self.name
// 作业,在资产页面,做一个功能,可以增删改查
笔记三 12 课
1,应用django的用户
from django.contrib.auth.models import User
class UserProfile(models.Model):
user = models.OneToOneField(User)
2.自关联需要家 related_name='xxx'
parent_comment = models.ForeignKey('Comment',blank=True,null=True,related_name='pid')
3.应用表在admin页面
在 app/admin.py 中编写下面内容
from django.contrib import admin
import models
admin.site.register(models.Article)
admin.site.register(models.Gategory)
admin.site.register(models.ThumbUp)
admin.site.register(models.Comment)
admin.site.register(models.UserProfile)
admin.site.register(models.UserGroups)
4.创建超级用户
Type 'manage.py help' for usage.
Lvnian:s10day12bbs root# python manage.py createsuperuser
Username (leave blank to use 'root'):
Email address:
Password:
Password (again):
Superuser created successfully.
Lvnian:s10day12bbs root#
5.获取文章
######views.py
def index(request):
articles = models.Article.objects.all().order_by('-publish_date')
return render(request,'index.html',{
'articles': articles
})
######index.html
{% for article in articles %}
{{ article }}
{% endfor %}
6.boostrap 中让div换行,用row
7.微信等小图标到 font-awesome中找
http://fontawesome.dashgame.com/
如微信的图标就直接应用:
但是是需要下下载font-awesomes 的css样式
并且应用它
8.
二次渲染,safe可以解析html标签:
{{ article.content |safe}}
9.编辑器
参考文档:http://archive.tinymce.com/wiki.php/Installation
第一步:下载tinymce编辑器,在本程序中已经下载好,在/static/plugins/tinymce目录中
第二步:在html文件中应用这个js问题,如下:
第三步:
第四步:在你需要的添加编辑起的地方应用下面代码
第五步,这个免费的编辑器的功能有点少,可以点击Advanced选择其他
免费的插件
也就说把上面第三部的内容换为下面的内容
第五部。这个编辑器上存到数据库的内容是html内容
10.把编辑器的内容上传到数据库
11.认证用户:
第一步:
login.html 文件如下:
{% extends 'index.html' %}
{% block container %}
{{ login_err }}
{% endblock %}
第二步:
views.html
def account_login(request):
if request.method == 'GET' :
return render(request,'login.html')
else:
print request.POST
username = request.POST.get('username')
passwd = request.POST.get('password')
user = authenticate(username=username,password=passwd)
if user is not None:
login(request,user)
user.userprofile.online = True
user.userprofile.save()
return HttpResponseRedirect("/")
else:
return render(request,'login.html',{
'login_err': "Wrong username or password!"
}
第三步:
url(r'^login/$', views.account_login, name='login'),
注意:登陆的用户不能是在userprofile中不存在的用户
11 html file upload 上传图片
第一步:
第二步:查看上传图片的路径
request.FILES ##查看上传图片的路径
第三步: 获取图片路径并保存到数据库
filename = handle_upload_file(self.requset,self.requset.FILES['head_img'])
bbs_obj.head_img = filename
12.查看某一篇文章的所有评论
>>> from bbs import models
>>> models.Article.objects.first()
>>> a=models.Article.objects.first()
>>> a.comment_set.select_related()
[, , , , , , , , , ]
>>>
>>> b=a.comment_set.select_related()[3]
>>> b.parent_comment
>>> b
>>>
>>> a.comment_set.select_related().count()
10
>>>
>>> a.comment_set.select_related().values()
[{'comment': u'A', u'user_id': 2, u'parent_comment_id': None, 'date': datetime.datetime(2016, 8, 9, 17, 43, 0, 844150, tzinfo=),
u'article_id': 1, u'id': 1}, {'comment': u'A2', u'user_id': 2, u'parent_comment_id': 1, 'date': datetime.datetime(2016, 8, 10, 12, 47, 6, 530839, tzinfo=),
u'article_id': 1, u'id': 2}, {'comment': u'A3', u'user_id': 2, u'parent_comment_id': 2, 'date': datetime.datetime(2016, 8, 12, 15, 18, 19, 856836, tzinfo=),
u'article_id': 1, u'id': 4}, {'comment': u'A4', u'user_id': 2, u'parent_comment_id': 4, 'date': datetime.datetime(2016, 8, 12, 15, 18, 34, 887493, tzinfo=),
u'article_id': 1, u'id': 5}, {'comment': u'A2-2', u'user_id': 2, u'parent_comment_id': 1, 'date': datetime.datetime(2016, 8, 12, 15, 19, 6, 761271, tzinfo=),
u'article_id': 1, u'id': 6}, {'comment': u'A3-3', u'user_id': 2, u'parent_comment_id': 2, 'date': datetime.datetime(2016, 8, 12, 15, 19, 45, 183586, tzinfo=),
u'article_id': 1, u'id': 7}, {'comment': u'A3-3-2', u'user_id': 2, u'parent_comment_id': 7, 'date': datetime.datetime(2016, 8, 12, 15, 20, 2, 480632, tzinfo=),
u'article_id': 1, u'id': 8}, {'comment': u'B', u'user_id': 1, u'parent_comment_id': None, 'date': datetime.datetime(2016, 8, 12, 15, 20, 46, 305339, tzinfo=),
u'article_id': 1, u'id': 9}, {'comment': u'B2-2', u'user_id': 1, u'parent_comment_id': 9, 'date': datetime.datetime(2016, 8, 12, 15, 21, 6, 357866, tzinfo=),
u'article_id': 1, u'id': 10}, {'comment': u'B2', u'user_id': 1, u'parent_comment_id': 9, 'date': datetime.datetime(2016, 8, 12, 15, 21, 15, 34450, tzinfo=),
u'article_id': 1, u'id': 11}]
>>>
>>> a.comment_set.select_related().values('comment','parent_comment_id')
[{'comment': u'A', 'parent_comment_id': None},
{'comment': u'A2', 'parent_comment_id': 1},
{'comment': u'A3', 'parent_comment_id': 2},
{'comment': u'A4', 'parent_comment_id': 4},
{'comment': u'A2-2', 'parent_comment_id': 1},
{'comment': u'A3-3', 'parent_comment_id': 2},
{'comment': u'A3-3-2', 'parent_comment_id': 7},
{'comment': u'B', 'parent_comment_id': None},
{'comment': u'B2-2', 'parent_comment_id': 9},
{'comment': u'B2', 'parent_comment_id': 9}]
>>>
>>> b=a.comment_set.select_related()[3]
>>> b.parent_comment
>>> b
>>>
>>>
>>> a.comment_set.select_related()
[, , , , , , , , , ]
>>> a.comment_set.select_related()[0]
>>> b=a.comment_set.select_related()[0]
>>> {b:3}
{: 3}
>>>
##上面说吗 b 实例可以当成为可以,后面的数字是值
如:
>>> {b:3789}
{: 3789}
>>>
>>> {dd:444}
{'ddd': 444}
>>>
###视频中错误是应为 A2评论到 其他文章中去了
13 .自定义标签
参考:https://docs.djangoproject.com/en/dev/howto/custom-template-tags/
第一步:在 app下创建templatetags包,也就是本案例的bbs下创建templatetags包如下:
bbs/templatetags/__init__.py
bbs/templatetags/poll_extras.py
第二步:编写poll_extras.py文件,编写成你需要的标签,下面编写的是,把数据转为大写字母
from django import template ###必须应用template模块
register = template.Library()
@register.filter
def test_tag(data):
print 'tag::: ' ,data
return data.upper()
第三步:在引用的html文件中使用
{% load poll_extras %}
第四步:在html中应用这个标签,如下: 把作者名称改为大写,它不能解析html内容
{{ article.author.name|test_tag }} ## 这中调用方式用于@register.filter装饰器,
如果是@register.simple_tag这种装饰器就需要用下面的调用方法,且这中装饰器可以解析html格式
{% test_tag2 article.author.name %}
14.分页
django 自带的分页:django paginator
参考:https://docs.djangoproject.com/en/1.10/topics/pagination/
>>> from django.core.paginator import Paginator
>>> objects = ['john', 'paul', 'george', 'ringo']
>>> p = Paginator(objects, 2)
>>> p.count
4
>>> p.num_pages ##一共多少页,也可说是最后一页的页数
2
>>> p.page_range
[1, 2]
>>>
>>> page1 = p.page(1)
>>> page1
>>> page1.object_list
['john', 'paul']
>>> page2 = p.page(2)
>>> page2.object_list
['george', 'ringo']
>>> page2.has_next()
False
>>> page2.has_previous()
True
>>> page2.has_other_pages()
True
>>> page2.next_page_number()
Traceback (most recent call last):
...
EmptyPage: That page contains no results
>>> page2.previous_page_number()
1
>>> page2.start_index() # The 1-based index of the first item on this page
3
>>> page2.end_index() # The 1-based index of the last item on this page
4
>>> p.page(0)
Traceback (most recent call last):
...
EmptyPage: That page number is less than 1
>>> p.page(3)
Traceback (most recent call last):
...
EmptyPage: That page contains no results
###################################
###################################
################################### 后端处理
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
from django.shortcuts import render
def listing(request):
contact_list = Contacts.objects.all() ###把内容取出来,但不是真正取出去。
paginator = Paginator(contact_list, 25) # Show 25 contacts per page
page = request.GET.get('page') ##前台说要去那一页,就提交到这
try:
contacts = paginator.page(page)
except PageNotAnInteger:
# If page is not an integer, deliver first page. ##如果页面不是一个整数,交付第一页
contacts = paginator.page(1)
except EmptyPage:
# If page is out of range (e.g. 9999), deliver last page of results.
contacts = paginator.page(paginator.num_pages) ##如果取的页数超过最大页数,就返回最后一页
return render(request, 'list.html', {'contacts': contacts}) ##把获取到的页面返回到前台
###################################
###################################
################################### 前端处理
{% for contact in contacts %}
{# Each "contact" is a Contact model object. #}
{{ contact.full_name|upper }}
...
{% endfor %}
###################################
###################################
################################### 前端处理,用bootstrap 实现, 作业:线上分页中的前后几页,而不是下面的全部页面都显示
13day聊天室笔记
1.生产者,消费者模型
django 的自带 Q
用户和用户聊天 :建立一个队列,在他们聊天的时候才建立
用户在群组聊天: 用户和群组的每个在线的用户都建立一个队列。
定时到服务端去消息,设置多长时间去取消息,就有多就的延迟。
客户端可以设置一直get固定的时长,时间一过,服务器就断开。服务器断开之后,客户端马上连接,再get固定时长,不断重复
>>> a.get(timeout=5) ##如果没有get到数据就保存get连接5秒,5秒后断开
2.消息队列:
>>> import Queue
>>> a = Queue.Queue()
>>> a
>>> a.put(123)
>>> a.put(234)
>>> a.get
>
>>> a.get()
123
>>> a.get()
234
>>> a.qsize()
0
>>> a.put(123)
>>> a.qsize()
1
>>> a.put(234)
>>> a.qsize()
2
>>>
>>> a.get(timeout=5) ##如果没有get到数据就保存get连接5秒,5秒后断开
Traceback (most recent call last):
File "", line 1, in
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/Queue.py", line 176, in get
raise Empty
Queue.Empty
>>>
3 建一个新的app
Lvnian:s10day12bbs root# python manage.py startapp web_qq
Lvnian:s10day12bbs root# ls
.idea 111.jpeg bbs manage.py statics web_qq ???????????????.txt
1.jpg 111_y4xE6o8.jpeg db.sqlite3 s10day12bbs templates ??????BBS
Lvnian:s10day12bbs root#
4.本这个web_qq关联起来
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'bbs',
'web_qq',
)
5.设置models
6.生产相关数据库表
Lvnian:s10day12bbs root# python manage.py makemigrations
Migrations for 'web_qq':
0001_initial.py:
- Create model QQGroup
Migrations for 'bbs':
0004_userprofile_friends.py:
- Add field friends to userprofile
Lvnian:s10day12bbs root# python manage.py migrate
Operations to perform:
Synchronize unmigrated apps: staticfiles, messages
Apply all migrations: sessions, admin, auth, contenttypes, web_qq, bbs
Synchronizing apps without migrations:
Creating tables...
Running deferred SQL...
Installing custom SQL...
Running migrations:
Rendering model states... DONE
Applying bbs.0004_userprofile_friends... OK
Applying web_qq.0001_initial... OK
Lvnian:s10day12bbs root#
7.创建聊天室web页面,和相关的url
第一步:把web_qq的相关url分离出来
1.在主urls中添加下面内容
from web_qq import urls as char_urls
url(r'^chat/', include(char_urls)),
2.在web_qq 中添加urls文件,写下面的文件
from django.conf.urls import url
import views
urlpatterns = [
url(r'^$', views.dashboard, name='chat'),
]
第二步:添加相应的views
from django.shortcuts import render
def dashboard(request):
return render(request,'web_qq/bashboard.html')
第三步:添加相应的bashboard.html
8.boostrap 聊天窗模版: http://v3.bootcss.com/javascript/#tabs
9.boostrap 聊天窗中的联系人模版:http://v3.bootcss.com/components/#list-group
10.循环取用户:
{% for contact in request.user.userprofile.friends.select_related %}
{{ contact.name }}
{% endfor %}
11. 点击那个用户,那个用户就高亮的javascript
{% block bottom-js %}
{% endblock %}
12.自定义属性
{{ contact.name }}
上面的contact-id="{{ contact.id }}"是自定义属性
13.点击那个用户,那个用户就高亮,并且聊天窗口切换到对于的用户聊天框中
{% for contact in request.user.userprofile.friends.select_related %}
{{ contact.name }}
{% endfor %}
####################################
14.敲回车键就发送消息到聊天窗口
function AddSentMagIntoBox(msg_text) {
var msg_div = "" +
"" + "{{ request.user.userprofile.name }}" + "" +
"" + new Date().toLocaleDateString() + "" +
"" + msg_text + "
" + "" ;
$(".dialog-box-content").append(msg_div);
$(".dialog-box-content").animate({ // 配合css中的/* overflow: auto; 消息框满屏情况下不要把消息谈到窗外 */ 。让消息在满屏的情况下,显示最新的消息在最下面
scrollTop : $(".dialog-box-content")[0].scrollHeight},300)
}
15.发送消息到后台
function SendMsg(msg) { // 把我是谁,我发送的消息,以及发送消息的类型 发送到后台
var msq_dic = { // 要发送的内容
'from_id':"{{ request.user.userprofile.id }}",
'to_id':$(".dialog-box-head span").attr("contact-id"),
'contact-type':$(".dialog-box-head span").attr("contact-type"),
'msg':msg,
}
// POST 发送 必须要待token才可以发送,不然出现403错误, JSON.stringify(msq_dic) 是把上面的msq_dic转化为json格式后发送到啊后台
//$.post("{% url 'char_send_msg' %}",{'data':msq_dic,'csrfmiddlewaretoken':$("input[name='csrfmiddlewaretoken']").val()},function(collback){
$.post("{% url 'char_send_msg' %}",{'data':JSON.stringify(msq_dic),'csrfmiddlewaretoken':$("input[name='csrfmiddlewaretoken']").val()},function(collback){
console.log(collback);
}); //end post
}
// {% url 'char_send_msg' %} 这个url 对于的就就说下面的内容。
def send_msg(request):
print request.POST
#print request.POST.get('data[msg]') ## 获取还没转为json格式的单个数据
data = request.POST.get('data') ## 获取前台传过来的所有数据
data = json.loads(data)
data['date'] = datetime.datetime.now().strftime("%Y-%m-%d %H:%M%S")
to_id = data.get('to_id')
#print to_id
contact_type = data.get('contact-type')
user_obj = models.bbs_models.UserProfile.objects.get(id=to_id)
print user_obj
if contact_type == 'single':
if not globals_msg_dic.has_key(to_id):
globals_msg_dic[to_id] = utils.Char() ## 初始化数据
globals_msg_dic[to_id].msq_queue.put(data)
print '\033[31;1, Push msg [%s] into user [%s] queue ' %(data['msg'],user_obj.name)
return HttpResponse('ok ')
#################################
#################################
#################################
$(document).ready(function () {
RefreshMsgs = setInterval(function () {
GetNewMsg();
},3000)
$("#content-list a").click(function () {
$(this).addClass("active");
$(this).siblings().removeClass("active");
SwitchChatBox(this); /* 定义一个切换聊天框函数 */
})
});
################
function GetNewMsg() {
$.get("{% url 'get_new_msg' %}",{'uid':"{{ request.user.userprofile.id }}"},function(callback){
console.log(callback);
$.each(callback,function (index,msg) {
pass
})//end each
}); //end get
}
7.徽章
-
14
Cras justo odio
8.页面切换,内容显示当前用户的,不显示老用户内容。
function SessionHandle(contact_id,contact_type,action) {
if(action == 'dump'){//如果是dump,那就是保存当前聊天页面
var current_dialog_content = $(".dialog-box-content").html();
all_dialog_sessions[contact_type][contact_id] = current_dialog_content
//console.log(all_dialog_sessions[contact_type][contact_id])
}else if(action == 'load'){// 如果是load,就是把切换后的,也就是指定的contact_id 的聊天记录加载出来
var new_dialog_content = ''
if(all_dialog_sessions[contact_type].hasOwnProperty(contact_id)){
new_dialog_content = all_dialog_sessions[contact_type][contact_id]
}
return new_dialog_content
}// if
} // func
9.
function SwitchChatBox(ele){
var current_uid = $(ele).attr("contact-id")
var current_dialog_type = $(ele).attr("contact-type");
var current_contact_name = $(ele).text();
var old_session_id = $(".dialog-box-head span").attr("contact-id");
var old_session_type = $(".dialog-box-head span").attr("contact-type");
SessionHandle(old_session_id,old_session_type,'dump')
var current_dialog_content = SessionHandle(current_uid,current_dialog_type,'load')
$(".dialog-box-content").html(current_dialog_content) // 注意后面还要加载新接受的内容
var dialog_head_html = "" + current_contact_name + "" ;
$(".dialog-box-head").html(dialog_head_html)
$(".dialog-box-content").animate({ // 配合css中的/* overflow: auto; 消息框满屏自动滚动到最底 */ 。让消息在满屏的情况下,显示最新的消息在最下面
scrollTop : $(".dialog-box-content")[0].scrollHeight},500);
}
//同时把这条消息保存到全局变量中
var msg_sender_name = $("#content-list a[contact-id='"+ msg.from_id +"']").text();
var msg_div= "" +
"" + msg_sender_name + "" +
"" + msg.date + "" +
"" +
"" + msg.msg + ""
var old_session_content = SessionHandle(msg.from_id,msg.contact_type,'load');
var new_session_content = old_session_content +msg_div ;
all_dialog_sessions[msg.contact_type][msg.from_id] = new_session_content