分类:'DJango' 的所有文章

动态加载javascript/json然后立即执行

晚上想写个json接口,类似delicious的那种webapi。

Python讨论组里有人建议替换已经加载的脚本的src属性,或者重新生成一个script然后加载。

但是这种方式为异步加载,也就是浏览器想啥时候加载完咱不知道,想要加载以后立即进行操作的就不能保证了。

Google一下动态加载javascript找到一大堆,看起来用XMLHttpRequest应该可行,试了一下,搞定了:

function change_style(style) {
    
var oXmlHttp = GetHttpRequest() ;
    
oXmlHttp.onreadystatechange = function()
    
{
        
if ( oXmlHttp.readyState == 4 )
        
{
            
if ( oXmlHttp.status == 200 || oXmlHttp.status == 304 )
            
{
                
txt = oXmlHttp.responseText;
                
alert(txt)
                
var oScript = document.createElement( "script" );
                
oScript.language = "javascript";
                
oScript.type = "text/javascript";
                
oScript.id = sId;
                
oScript.defer = true;
                
oScript.text = source;
                
document.body.appendChild( oScript );
            
}
            
else
            
{
                
alert('操作失败:' + oXmlHttp.statusText + '(' + oXmlHttp.status + ')' ) ;
            
}
        
}
    
}
 
    
url = 'http://127.0.0.1:8000/static/styles/pyg/' + style + '.js';
    
oXmlHttp.open('GET', url, true);
    
oXmlHttp.send(null);
}

这里有个更简单的方法(未验证),加载后执行一个helper函数,呵呵:

var head = document.getElementsByTagName('head')[0];
var script = document.createElement('script');
script.type = 'text/javascript';
script.onreadystatechange = function () {
    
if (this.readyState == 'complete') helper();
}
script.onload = helper;
script.src = 'helper.js';
head.appendChild(script);
  • Share/Bookmark

Django防止重复发评论

有一篇很好的文章讲如何防止重复发帖:Redirect After Post

发表评论的页面一般会redirect回到当前页,这时候浏览器reload/refresh会有对话框弹出,问是否提交。
这里贴一个防止refresh/reload提交的方法:

#post comment succeeded, let's show the comment
response = HttpResponseRedirect("/code/view/%d/#comment_form" % codee.id)
#stop duplicate pages
response['Expires'] = '0'
response['ExpiresAbsolute'] = 'Wed, 11 Jan 1984 05:00:00 GMT'
response['Cache-Control'] = 'no-cache, must-revalidate, max-age=0'
response['Pragma'] = 'no-cache'
return response

这样用户体验会好一些。

真正防止重复发帖的话,在server端做个验证就行。

  • Share/Bookmark

判断提交的表单中是否包含中文字

Some Chinese Please是用php写的wordpress插件。
基本原理是:英文spammer比较多,如果评论中没有中文字默认为spammer

上网查了一下Python做这个的代码,逻辑比较复杂,想了想,做了个判断是否包含非英语文字的:

str = comment.encode('utf-8')
if len(str) == len(comment):
    
raise forms.ValidationError('评论中必须包含中文字')

应该有作用。

  • Share/Bookmark

Django登陆以后重定向到请求登陆的页面

登陆和注销操作在网页编程上很常见,这两个操作经常需要在操作成功以后转入发出请求的页面。

比如用户正在浏览一篇文章,发现下载该文章的附件需要登录才能进行,这时候点击登陆链接转入登陆页面,输入用户名密码登陆成功以后,会自动转回原来的那篇文章所在的页面。(目前很多网站采用ajax方法弹出对话框登陆,效果更好一些)

怎么做呢?下面说的是django的实现,但是大多数的web framework都可以这么做。

注销操作
因为不需要单独的注销页面,相对简单,利用HTTP_REFERER,Django的注销页面这样写就行:

def logout_user(request):
    
logout(request)
    
return HttpResponseRedirect(request.META.get('HTTP_REFERER', '/'))

登录操作
登陆操作相对复杂,因为一般都有单独的登陆页面,如果登陆成功再取HTTP_REFERER就是登陆页面自己的url,而不是之前的那个页面。

可以利用django的session,在转入登陆的时候,用的是页面的get请求,这时候在session中记录HTTP_REFERER,用户输入用户名密码进行登陆的时候(Post请求),从session中取出即可:

def login_user(request):
    
if request.method == 'GET':
        
#记住来源的url,如果没有则设置为首页('/')
        
request.session['login_from'] = request.META.get('HTTP_REFERER', '/')
        
#TODO:显示登陆页面,blablabla
    
elif request.method == 'POST':
        
#TODO: 用户登录操作,blablabla
        
#重定向到来源的url
        
return HttpResponseRedirect(request.session['login_from'])

最后的重定向,有时候需要用户感觉到被重定向回去了,就写个简单的页面告诉用户两秒以后跳转,然后改改相应的login代码就行:

<p>两秒钟后转入如下链接,如果长时间没有响应请直接点击:</p>
<p><a href="{{ refresh_url }}">{{ refresh_url }}</a></p>
<meta http-equiv="refresh" content="2;url={{ refresh_url }}">
  • Share/Bookmark

django起shell的时候遇到code.py的问题

用Django建了一个工程,然后生成了一个叫做code的项目,再用manage.py shell的时候报错了:

Traceback (most recent call last):
  File "..\manage.py", line 11, in <module>
    execute_manager(settings)
  File "c:\python\Lib\site-packages\django\core\management.py", line 1672, in execute_manager
    execute_from_command_line(action_mapping, argv)
  File "c:\python\Lib\site-packages\django\core\management.py", line 1567, in execute_from_command_line
    action_mapping[action](options.plain is True)
  File "c:\python\Lib\site-packages\django\core\management.py", line 1284, in run_shell
    code.interact()
AttributeError: 'module' object has no attribute 'interact'

探究了一下,发现python自己有个code.py,专用来做interact shell,我自己这边有个code文件夹,结果直接import的时候就出问题了。

项目做了不少了,不想改了,干脆把c:\python\lib下面的code.py做了一个copy,叫做ohmycode.py,然后到managemeng.py里面import ohmycode之后的代码都从”code” 改成 “ohmycode”。

搞定。

我知道这样有风险,以后部署到其他机器上的时候会有问题,不过暂时先这么干了,在这里记一下。

顺便抱怨一下python的标准库的引用,我觉得都应该放在一个目录下,顶多引用的时候多写点儿代码,也不至于冲突,现在可好,c:\python\lib下一百多个库,说不定哪天起个文件名就撞在枪口上了。

  • Share/Bookmark

« 上一页下一页 »