笔记一 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" %}
<li style="background-color: red"> {{ k }}::{{ v }}</li>
{% else %}
<li style="background-color: blue"> {{ k }}::{{ v }}</li>
{% endif %}
3. django 的for 循环,也就是在{% python命令 %}
如:
{% for k,v in info_data.items %}
<li> {{ k }}::{{ v }}</li>
{% 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文件中的用法,如下
<ul class="nav navbar-nav navbar-left">
<li><a href="{% url 'index' %}">首页</a></li>
<li><a href="{% url 'host' %}">主机</a></li>
<li><a href="{% url 'asset' %}">资产</a></li>
<li><a href="{% url 'audit' %}">审计</a></li>
</ul>
上面的首页,本应该写为:
<li><a href="/host/">主机</a></li>
现在仅仅用{% 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' %}
<!DOCTYPE html>
{% block left-sidebar %}
aaa
{% endblock %}
{% block right-sidebar %}
<h1>host</h1>
{% endblock %}
2.django获取访问的路径
{{ request.path }}
3.切换导航栏高亮
<script type="text/javascript">
$(document).ready(function () {
$("#navbar a[href='{{ request.path }}']").parent().addClass("active");
})
</script>
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'),
]
<ul class="nav navbar-nav navbar-left">
<li><a href="/">首页</a></li>
<li><a href="{% url 'host' %}">主机</a></li>
<li><a href="{% url 'asset' %}">资产</a></li>
<li><a href="{% url 'audit' %}">审计</a></li>
</ul>
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 %}这个
<div class="col-md-4 ">
<form method="post">{% csrf_token %}
<input type="text" name="username" placeholder="username" />
<br>
<input type="password" name="password" placeholder="password" />
<br>
<input type="submit" class="btn btn-info" value="登陆" />
</form>
</div>
// <input type="hidden" name="csrfmiddlewaretoken" value="2m2Iz2BVvl0QhkLXHfI0APTqb6MzD25N"> 这个value就是令牌
print request.POST ##得到的内容
<QueryDict: {u'username': [u'GAS'], u'csrfmiddlewaretoken': [u'2m2Iz2BVvl0QhkLXHfI0APTqb6MzD25N'], u'password': [u'ASDSD']}>
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)
<Host: gaogdtest>
>>>
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)
<Host: gaogdtest01>
>>>
批量给主机添加组: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 %}
<a href="##">{{ request.user }}</a>
{% else %}
<a href="/login/">登录</a>
{% 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 %}
<li>
{{ group.name }}
</li>
{{ group.host_set.select_related }}
{% endfor %}
这个asset的内容
{{ request.user.userprofile.hosts.select_related }}
<ul>
{% for group in request.user.userprofile.host_groups.select_related %}
<li>
{{ group.name }}
</li>
<ul>
{% for host in group.host_set.select_related %}
<li>
{{ host.hostname }} --->{{ host.ip_addr }}
</li>
{% endfor %}
</ul>
{% endfor %}
</ul>
#############
[<Host: ubuntu>]
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 }}
<br>
{% endfor %}
6.boostrap 中让div换行,用row
<div class="row">
</div>
7.微信等小图标到 font-awesome中找
http://fontawesome.dashgame.com/
如微信的图标就直接应用:<i class="fa fa-wechat"></i>
但是是需要下下载font-awesomes 的css样式
并且应用它
<link rel="stylesheet" href="/static/font-awesome/css/font-awesome.min.css">
8.
<pre></pre>
二次渲染,safe可以解析html标签:
{{ article.content |safe}}
9.编辑器
参考文档:http://archive.tinymce.com/wiki.php/Installation
第一步:下载tinymce编辑器,在本程序中已经下载好,在/static/plugins/tinymce目录中
第二步:在html文件中应用这个js问题,如下:
<script src="/static/plugins/tinymce/js/tinymce/tinymce.min.js"> </script>
第三步:
<script src="/static/plugins/tinymce/js/tinymce/tinymce.min.js"> </script>
<script type="text/javascript">
tinymce.init({
selector: "#create_bbs"
});
</script>
第四步:在你需要的添加编辑起的地方应用下面代码
<form method="post">{% csrf_token %}
<textarea id="create_bbs" name="content" ></textarea>
</form>
第五步,这个免费的编辑器的功能有点少,可以点击Advanced选择其他
免费的插件
也就说把上面第三部的内容换为下面的内容
<script src="/static/plugins/tinymce/js/tinymce/tinymce.min.js"> </script>
<script type="text/javascript">
tinymce.init({
selector: "#create_bbs",
theme: "modern",
width: 800,
height: 300,
plugins: [
"advlist autolink link p_w_picpath lists charmap print preview hr anchor pagebreak spellchecker",
"searchreplace wordcount visualblocks visualchars code fullscreen insertdatetime media nonbreaking",
"save table contextmenu directionality emoticons template paste textcolor"
],
content_css: "css/content.css",
toolbar: "insertfile undo redo | styleselect | bold italic | alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | l ink p_w_picpath | print preview media fullpage | forecolor backcolor emoticons",
style_formats: [
{title: 'Bold text', inline: 'b'},
{title: 'Red text', inline: 'span', styles: {color: '#ff0000'}},
{title: 'Red header', block: 'h1', styles: {color: '#ff0000'}},
{title: 'Example 1', inline: 'span', classes: 'example1'},
{title: 'Example 2', inline: 'span', classes: 'example2'},
{title: 'Table styles'},
{title: 'Table row 1', selector: 'tr', classes: 'tablerow1'}
]
});
</script>
第五部。这个编辑器上存到数据库的内容是html内容
10.把编辑器的内容上传到数据库
11.认证用户:
第一步:
login.html 文件如下:
{% extends 'index.html' %}
{% block container %}
<div class="col-md-4">
</div>
<div class="col-md-4">
<form method="post" action="{% url 'login' %}">{% csrf_token %}
<input type="text" name="username" placeholder="username" /> <br>
<input type="password" name="password" placeholder="password" /><br>
<input type="submit" value="Login" class="btn btn-success" />
</form>
<p style="color: red">{{ login_err }}</p>
</div>
{% 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 上传图片
第一步:
<form class="form-horizontal" method="post" action="{% url 'create_article' %}" enctype="multipart/form-data"> {% csrf_token %}
<div class="form-group">
<label for="inputEmail3" class="col-sm-2 control-label">图片</label>
<div class="col-sm-10">
<input type="file" name="head_img">
</div>
</div>
</form>
第二步:查看上传图片的路径
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()
<Article: test01>
>>> a=models.Article.objects.first()
>>> a.comment_set.select_related()
[<Comment: A>, <Comment: A2>, <Comment: A3>, <Comment: A4>, <Comment: A2-2>, <Comment: A3-3>, <Comment: A3-3-2>, <Comment: B>, <Comment: B2-2>, <Comment: B2>]
>>>
>>> b=a.comment_set.select_related()[3]
>>> b.parent_comment
<Comment: A3>
>>> b
<Comment: A4>
>>>
>>> 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=<UTC>),
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=<UTC>),
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=<UTC>),
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=<UTC>),
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=<UTC>),
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=<UTC>),
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=<UTC>),
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=<UTC>),
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=<UTC>),
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=<UTC>),
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
<Comment: A3>
>>> b
<Comment: A4>
>>>
>>>
>>> a.comment_set.select_related()
[<Comment: A>, <Comment: A2>, <Comment: A3>, <Comment: A4>, <Comment: A2-2>, <Comment: A3-3>, <Comment: A3-3-2>, <Comment: B>, <Comment: B2-2>, <Comment: B2>]
>>> a.comment_set.select_related()[0]
<Comment: A>
>>> b=a.comment_set.select_related()[0]
>>> {b:3}
{<Comment: A>: 3}
>>>
##上面说吗 b 实例可以当成为可以,后面的数字是值
如:
>>> {b:3789}
{<Comment: A>: 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内容
<a>{{ article.author.name|test_tag }}</a> ## 这中调用方式用于@register.filter装饰器,
如果是@register.simple_tag这种装饰器就需要用下面的调用方法,且这中装饰器可以解析html格式
<a>{% test_tag2 article.author.name %}</a>
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
<Page 1 of 2>
>>> 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 }}<br />
...
{% endfor %}
<div class="pagination">
<span class="step-links">
{% if contacts.has_previous %} ##判断后端传来的页数,有没有上一页
<a href="?page={{ contacts.previous_page_number }}">previous</a>
{% endif %}
<span class="current">
Page {{ contacts.number }} of {{ contacts.paginator.num_pages }}.
</span>
{% if contacts.has_next %} ##判断后端传来的页数,有没有下一页
<a href="?page={{ contacts.next_page_number }}">next</a>
{% endif %} ### ?page ,加上'?'问号。 就是一个get方法。
</span>
</div>
###################################
###################################
################################### 前端处理,用bootstrap 实现, 作业:线上分页中的前后几页,而不是下面的全部页面都显示
<nav>
<ul class="pagination">
{% if articles.has_previous %}
<li>
<a href="?page={{ articles.previous_page_number }}" aria-label="Previous">
<span aria-hidden="true">
«
</span>
</a>
</li>
{% else %}
<li>
<a href="#" aria-label="Previous">
<span aria-hidden="true">
«
</span>
</a>
</li>
{% endif %}
{% for p_num in articles.paginator.page_range %}
{% if articles.number == p_num %}
<li class="active">
<a href="#">
{{ articles.number }}
<span class="sr-only">{{ articles.number }}
</span>
</a>
</li>
{% else %}
<li >
<a href="?page={{ p_num }}">
{{ p_num }}
</a>
</li>
{% endif %}
{% endfor %}
{% if articles.has_next %}
<li>
<a href="?page={{ articles.next_page_number }}" aria-label="Next">
<span aria-hidden="true">
»
</span>
</a>
</li>
{% else %}
<li>
<a href="#" aria-label="Next">
<span aria-hidden="true">
»
</span>
</a>
</li>
{% endif %}
</ul>
</nav>
13day聊天室笔记
1.生产者,消费者模型
django 的自带 Q
用户和用户聊天 :建立一个队列,在他们聊天的时候才建立
用户在群组聊天: 用户和群组的每个在线的用户都建立一个队列。
定时到服务端去消息,设置多长时间去取消息,就有多就的延迟。
客户端可以设置一直get固定的时长,时间一过,服务器就断开。服务器断开之后,客户端马上连接,再get固定时长,不断重复
>>> a.get(timeout=5) ##如果没有get到数据就保存get连接5秒,5秒后断开
2.消息队列:
>>> import Queue
>>> a = Queue.Queue()
>>> a
<Queue.Queue instance at 0x104e09050>
>>> a.put(123)
>>> a.put(234)
>>> a.get
<bound method Queue.get of <Queue.Queue instance at 0x104e09050>>
>>> 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 "<stdin>", line 1, in <module>
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
<div>
<!-- Nav tabs -->
<ul class="nav nav-tabs" role="tablist">
<li role="presentation" class="active"><a href="#home" aria-controls="home" role="tab" data-toggle="tab">Home</a></li>
<li role="presentation"><a href="#profile" aria-controls="profile" role="tab" data-toggle="tab">Profile</a></li>
<li role="presentation"><a href="#messages" aria-controls="messages" role="tab" data-toggle="tab">Messages</a></li>
<li role="presentation"><a href="#settings" aria-controls="settings" role="tab" data-toggle="tab">Settings</a></li>
</ul>
<!-- Tab panes -->
<div class="tab-content">
<div role="tabpanel" class="tab-pane active" id="home">...</div>
<div role="tabpanel" class="tab-pane" id="profile">...</div>
<div role="tabpanel" class="tab-pane" id="messages">...</div>
<div role="tabpanel" class="tab-pane" id="settings">...</div>
</div>
</div>
9.boostrap 聊天窗中的联系人模版:http://v3.bootcss.com/components/#list-group
<div class="list-group">
<a href="#" class="list-group-item active">
Cras justo odio
</a>
<a href="#" class="list-group-item">Dapibus ac facilisis in</a>
<a href="#" class="list-group-item">Morbi leo risus</a>
<a href="#" class="list-group-item">Porta ac consectetur ac</a>
<a href="#" class="list-group-item">Vestibulum at eros</a>
</div>
10.循环取用户:
{% for contact in request.user.userprofile.friends.select_related %}
{{ contact.name }}
{% endfor %}
11. 点击那个用户,那个用户就高亮的javascript
{% block bottom-js %}
<script type="text/javascript">
$(document).ready(function () {
$("#content-list a").click(function () {
$(this).addClass("active");
$(this).siblings().removeClass("active");
})
})
</script>
{% endblock %}
12.自定义属性
<a contact-id="{{ contact.id }}" href="#" class="list-group-item ">
{{ contact.name }}
</a>
上面的contact-id="{{ contact.id }}"是自定义属性
13.点击那个用户,那个用户就高亮,并且聊天窗口切换到对于的用户聊天框中
<div class="list-group" id="content-list">
{% for contact in request.user.userprofile.friends.select_related %}
<a contact-id="{{ contact.id }}" contact-type="single" href="#" class="list-group-item ">
{{ contact.name }}
</a>
{% endfor %}
</div>
####################################
<script type="text/javascript">
$(document).ready(function () {
$("#content-list a").click(function () {
$(this).addClass("active");
$(this).siblings().removeClass("active");
SwitchChatBox(this); /* 定义一个切换聊天框函数 */
})
});
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 dialog_head_html = "<span contact-id='"+ current_uid + "' contact-type='" + current_dialog_type + "'>" + current_contact_name + "</span>" ;
$(".dialog-box-head").html(dialog_head_html)
}
</script>
14.敲回车键就发送消息到聊天窗口
function AddSentMagIntoBox(msg_text) {
var msg_div = "<div class='pull right'>" +
"<span>" + "{{ request.user.userprofile.name }}" + "</span>" +
"<span>" + new Date().toLocaleDateString() + "</span>" +
"<p>" + msg_text + "</p>" + "</div>" ;
$(".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.徽章
<ul class="list-group">
<li class="list-group-item">
<span class="badge">14</span>
Cras justo odio
</li>
</ul>
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 = "<span contact-id='"+ current_uid + "' contact-type='" + current_dialog_type + "'>" + current_contact_name + "</span>" ;
$(".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= "<div class='row'>" +
"<span>" + msg_sender_name + "</span>" +
"<span>" + msg.date + "</span>" +
"</div>" +
"<div>" + msg.msg + "</div>"
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
转载于:https://blog.51cto.com/lvnian/1856434