Archive for django

配置的官方文档:http://docs.mongoengine.org/en/latest/django.html,安装的过程就不记了。 主要碰到的问题: 在按照文档配置完settings.py后,我写了登录代码。发现提示错误: settings.DATABASES is improperly configured. Please supply the ENGINE value. Check settings documentation for more details. 这个明显说databases配置错误。但是我准确对照配置没问题,然后从网上找资料也没有结果。 然后我又看mongoengine里面的auth,还是不知道问题在哪里。然后我又找django的auth模块,突然想到: 肯定是调用这里出的错啊,然后我看浏览器显示错误的backtrack。 /usr/local/lib/python2.7/dist-packages/django/contrib/auth/views.py in login

    current_site = get_current_site(request)
啊哈,还是思路不清晰,瞎找。然后吧INSTALLED_APP里面的django.contrib.sites注释掉,成功。

Continue

以前都是用的django定义的user model,不用的字段也都这么放着,显然很不科学。 今天就看着一下文档,找到了方法,但是还是没用。。 https://docs.djangoproject.com/en/1.5/topics/auth/customizing/ 最彻底的修改settings的auth_user_model来指定user的model。

Continue

需要一个settings文件template-context-processors的配置:https://docs.djangoproject.com/en/1.5/ref/settings/#template-context-processors官网文档有默认配置,本身生成的settings文件没有这个定义,使用默认配置。 然后多添加一行:

'django.core.context_processors.request',

就ok了
 

Continue

错误主要是在forms.py里面,想添加text文本编辑框,然后写了一个forms.TextField().....这不是重点,重点是我把views里的代码也写完,访问调试的时候,django页面提示View does not exist in module news.views。 views.py文件是一定存在的,不知道错在哪里。googel关键字找到so上说,用manage.py shell会提供更多信息。然后我再shell里导入views ,发现报前边的错误。修改,运行,然后正常了。

Continue

先说说我以前的做法:models.py里单纯的就是几个表,几个字段;forms.py里除了除了form的定义,把form数据的验证也放到这里来;view.py里是剩下的所有东西。 现在的想法(还没做):在models.py里面的类加上一些简单的处理方法,比如获取相关分类表里面的名称。forms.py里面加上save操作。 以前在django群里讨论过这个问题,大牛说逻辑处理最好不要放到views里面。这次写程序,又多瞅了几眼文档,感觉这样的好处确实很多,程序更容易读懂,减少代码行数,提高了代码复用,views.py文件肯定更加清晰。  

Continue

django中csrf的验证: Django是在post中有一个字段CsrfViewMiddleware 进行相关验证,验证过程很简单,从Cookie中拿出token,然后从POST中拿出csrfmiddlewaretoken,然后块俩做一个字符匹配。因为恶意网站无法读取你的Cookie(因为浏览器的同源策略),所以无法获得Cookie里的CSRF Token,无法伪造出csrf,POST就会失败,这样就不会产生安全问题。 ajax提交post表单时,从网上找到一个感觉不错的方法记录。

function getCookie(sName){
var aCookie=document.cookie.split("; ");
for(var i=0;i<aCookie.length;i++){var aCrumb=aCookie[i].split("=");if(sName==aCrumb[0])
return(aCrumb[1]);}return null;}
在需要提交表单的地方,加入的数据是getCookie('csrftoken') 字段名为csrfmiddlewaretoken

Continue

很简单的代码,记录一下。

    import Image
    image = Image.open('a.jpg')
    import cStringIO
    buf = cStringIO.StringIO()
    image.save(buf, image.format,quality=75)
    data = buf.getvalue()
    a = u.writeFile('/this/logo.jpg',data,True)
应用在 使用django,用户上传图片后,将图片转存到别的服务器。但是转存需要对图片进行处理,但是quality设定的保存,不知道可不可以在不是image.save()的时候。写的这个是保存时放到内存,然后直接提交到图片服务器。

Continue

当需要将上传的文件保存到别的服务器,而又不修改views里的代码,下面可能对你有点用。 Python26\Lib\site-packages\django\core\files\storage.py 这个文件里有一个FileSystemStorage类,类里的函数_save()进行了上传文件的保存。先上代码:

    def _save(self, name, content):
        full_path = self.path(name)
        print full_path,name
        # Create any intermediate directories that do not exist.
        # Note that there is a race between os.path.exists and os.makedirs:
        # if os.makedirs fails with EEXIST, the directory was created
        # concurrently, and we can continue normally. Refs #16082.
        directory = os.path.dirname(full_path)
        if not os.path.exists(directory):
            try:
                os.makedirs(directory)
            except OSError, e:
                if e.errno != errno.EEXIST:
                    raise
        if not os.path.isdir(directory):
            raise IOError("%s exists and is not a directory." % directory)

        # There's a potential race condition between get_available_name and
        # saving the file; it's possible that two threads might return the
        # same name, at which point all sorts of fun happens. So we need to
        # try to create the file, but if it already exists we have to go back
        # to get_available_name() and try again.

        while True:
            try:
                # This file has a file path that we can move.
                if hasattr(content, 'temporary_file_path'):
                    file_move_safe(content.temporary_file_path(), full_path)
                    content.close()

                # This is a normal uploadedfile that we can stream.
                else:
                    # This fun binary flag incantation makes os.open throw an
                    # OSError if the file already exists before we open it.
                    fd = os.open(full_path, os.O_WRONLY | os.O_CREAT | os.O_EXCL | getattr(os, 'O_BINARY', 0))
                    try:
                        locks.lock(fd, locks.LOCK_EX)
                        for chunk in content.chunks():
                            os.write(fd, chunk)
                    finally:
                        locks.unlock(fd)
                        os.close(fd)
            except OSError, e:
                if e.errno == errno.EEXIST:
                    # Ooops, the file exists. We need a new file name.
                    name = self.get_available_name(name)
                    full_path = self.path(name)
                else:
                    raise
            else:
                # OK, the file save worked. Break out of the loop.
                break

        if settings.FILE_UPLOAD_PERMISSIONS is not None:
            os.chmod(full_path, settings.FILE_UPLOAD_PERMISSIONS)

        return name
代码在这个文件的158行,函数传入参数name,第二句的print语句是我自己加上的,name路径就是存入数据库的路径,full_path路径是全路径,所以调用self.path的作用不言而喻了(代码在242行)。这里不需要全路径。 再往下两个if语句9行,功能:去掉文件名(就是文件夹路径),判断是否存在,不存在创建,然后创建不成功报错。这里也需要创建文件夹目录。 再往下的while语句就是存储文件代码了(\(≧▽≦)/激动~)。第一个if语句不明白是什么意思,在前面不知道怎么有这个属性,我也没往前找,不过应该不碍事,解释中介绍说普通上传在else里面。else里面的代码我只懂for循环,那个locks,在同一目录下有locks.py,看到一堆windows接口没兴趣研究,看注释好像是“有两个线程同时对同名文件写文件,会重新获取文件名”涉及到下面的except。这里直接设置保存图片代码。 最后的if语句应该是设置文件夹的权限。 找到这个文件,开始乱找一气,从models里的save开始没找到。后来想起调试了,没有设置错的上传路径,报错“Attempted access to '\a.jpg' denied”。然后根据Traceback,找到了文件。记录下执行顺序: views里的save(),下面省略若干,到了\lib\site-packages\django\db\models\fields\files.py 249行 file.save(file.name, file, save=False), 86行 self.name = self.storage.save(name, content) 然后到了文件\lib\site-packages\django\core\files\storage.py 44行 name = self.get_available_name(name) , 70行 while self.exists(name):, 230行 return os.path.exists(self.path(name)), 没错时,在45行,转到_save函数。

Continue

配置文件settings.py:

if 'SERVER_SOFTWARE' in os.environ:
    from bae.core import const
    DATABASES = {
        'default': {
            'ENGINE': 'django.db.backends.mysql', 
            'NAME': 'XXX',
            'USER': const.MYSQL_USER, 
            'PASSWORD': const.MYSQL_PASS,  
            'HOST': const.MYSQL_HOST,   
            'PORT': const.MYSQL_PORT, 
        }
    }
else:
    DATABASES = {
        'default': {
            'ENGINE': 'django.db.backends.mysql', 
            'NAME': 'baidu', 
            'USER': 'root',
            'PASSWORD': '',    
            'HOST': 'localhost',                   
            'PORT': '3306',                      
        }
    }
这里是django应用数据库的配置,具体可以参考官网:http://developer.baidu.com/wiki/index.php?title=%E5%B8%AE%E5%8A%A9%E6%96%87%E6%A1%A3%E9%A6%96%E9%A1%B5/%E4%BA%91%E7%8E%AF%E5%A2%83/WEB%E5%BC%80%E5%8F%91%E6%A1%86%E6%9E%B6 数据库需要先在本地导出来,然后用官网提供的phpmyadmin导入到bae数据库中。这里我只用到session表,直接执行sql语句简历一个django_session表就搞定了。

Continue

先记录一个无意在官网看到的有用的知识,不过没有测试,官网介绍很清楚。 先写地址:https://docs.djangoproject.com/en/1.4/ref/forms/widgets/#selectdatewidget 前面记录文章《django 前端时间控件移植记录》是将后台的功能移植到前台,现在可以直接创建SelectDateWidget forms进行设计了。 具体的效果我也没有试过,先记录。 说正题: 先上官网链接:https://docs.djangoproject.com/en/1.4/ref/forms/api/#django.forms.Form.initial f = ContactForm(initial={'subject': 'Hi there!'}) 后面再补充初始化form数据的代码。

Continue