django作为python非常流行的网站框架得到越来越多的应用。
在笔者构建CINPredictor期间,想构建一个留言板方便用户交流。于是寻找较好的途径。Django版本更新很快,但是由于笔者有多个django项目运行在一个环境中,前期有几个计算框架以来一些较为久远的计算包,所以短期内不打算更新django版本。高版本的django在pypi上面有插件,大家可以去搜索安装。我们这里需要自定义一些功能所以选择自己写。
django作为python非常流行的网站框架得到越来越多的应用。
在笔者构建CINPredictor期间,想构建一个留言板方便用户交流。于是寻找较好的途径。Django版本更新很快,但是由于笔者有多个django项目运行在一个环境中,前期有几个计算框架以来一些较为久远的计算包,所以短期内不打算更新django版本。高版本的django在pypi上面有插件,大家可以去搜索安装。我们这里需要自定义一些功能所以选择自己写。
本篇文章:python2.7.6+Django1.5.2
(1)部署留言板。主要根据这篇文章来部署:
http://blog.sina.com.cn/s/blog_a3f0d68201010vxh.html#cmt_2426257
http://www.tuicool.com/articles/aYneUj
主要实现注册,登录,分页等功能。这里面可以稍微做一些改进,所有模板结合Bootstrap模板优化,分页功能可以增加一个详情页面,这样也是为了实现用户评论做基础。其次,登录注册等功能可以根据自带的功能来写也可以自己编写优化版本的函数,这样可以自定义模板位置以及url等。
还有一个改进的地方就是导航,判断是否登录,从而显示登录,注册,修改密码等选项。这里遇到一个小问题:
如果自己写分页函数不用ListView 这个类函数那么在模板里面是可以通过{% if request.user.is_authenticated %}来判断是否登录的,但是如果使用ListView来做分页,就会出现无法在模板中获取request的问题。
解决方法:
当你在模板(template)中想访问request.session时会发现session不存在,即使将RequestContext加入到render_to_response中也无法获取。这时你需要查看下你的Context Processor 是否将request考虑进去了。也就是说你的setting.py中需要包含request对象。
TEMPLATE_CONTEXT_PROCESSORS = (
“django.contrib.auth.context_processors.csrf”,
“django.contrib.auth.context_processors.auth”,
“django.core.context_processors.request”,
)
只要在这里将request包含了,最后在view中使用render_to_response(“index.html”,{},context_instance = reqContext)就能够在模板中用{{request.session}}来访问session了。
这里的TEMPLATE_CONTEXT_PROCESSORS本来是没有的,需要增加这个变量。后两行增加后确实可以了。
(2)无刷新评论系统:
主要参考这篇文章:http://www.mamicode.com/info-detail-473954.html
首先是model:
1 2 3 4 5 6 7 |
class Replay(models.Model): content = models.TextField() post = models.ForeignKey(Post) replay_time = models.DateTimeField(u‘回复时间‘,editable=False) replay_user = models.CharField(max_length=30,editable=True) def __unicode__(self): return self.replay_time |
客服端Form表单:
1 2 |
<form id="user_content" enctype="multipart/form-data" method="‘post‘"><textarea id="id_content" cols="40" name="content" rows="10"></textarea> <input id="‘put‘" type="submit" value="提交" /></form> |
表单很简单,只列出了核心代码。
关键部分,提交评论的JS代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
<script> $(function() { $("#user_content").submit(function(){ var content = $("#id_content").val(); $.ajax({ type:"post", dataType:"json", url:"/replays/{{post_id}}/", data: { ‘content‘: content, }, success: function(data){ $(‘#user_content‘)[0].reset(); var newcomment = "<li class=\"contents\">" + "<div class=\"name\">你:</div>"+ "<div class=\"neir\">"+"<p>"+data.content+"</p>"+"</div>"+ "<div class=\"geceng\"></div>"+ "<div class=\"time\">回复时间:刚刚</div>"+ "<div class=\"geceng\"></div>"+ "</li>" $(".con").append(newcomment); } }); return false; }); }); </script> |
Django的模板:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
<div id = "comm"> <ul class = ‘con‘> {% for replay in replays %} <div class=‘cont‘> <div class=‘contents‘> <div class=‘name‘> {%if replay.replay_user %} {{replay.replay_user}}:</br> {%else%} 匿名:</br> {%endif%} </div> <div class=‘neir‘> <pre>{{ replay.content }}</pre> </div> <div class=‘time‘> 回复时间:{{replay.replay_time|date:"Y-m-d"}} </div></div></div> {% endfor %} </ul> </div> |
其中class = ’con’ 这个类,我的目的就是在这个类下面添append一个div,这个div里面的内容就是最新评论的内容。
Django的views;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
@csrf_exempt def replays(req,post_id): if req.is_ajax(): content = req.POST.get(‘content‘,None) if content: item=Post.objects.get(id=post_id) Replay.objects.create(content=content,post=item,replay_time=datetime.datetime.today(),replay_user= req.COOKIES.get(‘username‘,‘‘))#将评论写进数据库 return HttpResponse(json.dumps({"content":content})) else: form = ReplayForm() post_id=post_id replays = Post.objects.get(id=post_id).replay_set.all()#一条帖子的所有评论 num = int(len(replays)) title = Post.objects.get(id=post_id).title content = Post.objects.get(id=post_id).content username = req.COOKIES.get(‘username‘,‘‘) return render_to_response(‘replays.html‘,{ ‘content‘:content, ‘post_id‘:post_id, ‘num‘:num, ‘title‘:title, ‘replays‘:replays, ‘username‘:username, ‘form‘:form, },context_instance=RequestContext(req)) |
整个Ajax的流程是这样的:
1. 用户在Textarea里面输入内容,然后点击提交按钮,触发submit事件,触发return false,页面禁止刷新。
2. 之后获取Textarea里面的内容传给变量content。
3. 然后就是传送数据,在ajax函数里面定义传输的方式:post,数据类型:json,url(这里填写的url要对应到相应的views函数),data我这里面只有content。
4. ajax传送到服务器端,然后服务器端进行接收,这里replays函数将content存储在数据库中,然后返回一个HttpResponse响应,里面content作为json数据类型。
5. 这时ajax执行success:$(‘#user_content‘)[0].reset()是将表单内容清空,防止用户重复提交表单,我将回复的内容赋值给变量newcomment,这是一个html的语句,$(“.con”).append(newcomment):我将这个html语句写在一个指定的位置,就实现了页面无刷新提交。
整个过程就是这样的。注意这里面的缩进和引号,请自行修正。
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
这个评论系统也有一些小缺陷,比如request.COOKIES.user,有时候并不好使,可以根据实际需要改成request.user.
(3)有了这些之后,我们还有一个问题没解决,那就是验证码的问题。在pypi里面有许多可供选择的验证码工具,但是需要兼容django1.5.2 而且不要在app里面做过多设置。最终我们选择简单的验证问题插件django-simple-math-captcha(https://github.com/alsoicode/django-simple-math-captcha)这个工具真的超级简单,只需要在forms里面引入即可,在表单提交的时候会一起验证。不需要任何多的设置。
安装:运行pip install django-simple-math-captcha
用法一:连同其他字段一起验证
1 2 3 4 5 6 |
from simplemathcaptcha.fields import MathCaptchaField class MsgPostForm(forms.Form): title = forms.CharField(label='Title', max_length=70) content = forms.CharField(label='Content', widget=forms.Textarea) email = forms.CharField(label='E-mail', max_length=70) captcha = MathCaptchaField() |
用法二:单独验证:
1 2 3 |
from simplemathcaptcha.fields import MathCaptchaField class Single_Math_Captcha(forms.Form): captcha = MathCaptchaField() |
+++++++++++++++++++++++++++++++++++++++++++++++++++++
这三大步骤,可以实现自定义的用户登录,留言,评论等功能。
来源:本站原创
原创文章,作者:ifyoung,如若转载,请注明出处:https://www.drugfoodai.com/messageboard.html