今天接到一个电话面试,主要问了一些项目上的知识。有些答得不好,故写写博客,算总结下吧。
- django框架,MVC?不是,是MTV.
- 了解queryset吗?
- group表管理,friend表如何管理的?
- web聊天室聊天记录如何保存?没完成。
- session管理;django登陆后关闭浏览器,再次打开浏览器,进入项目,发现还是已经登陆到项目中了。这是一个BUG.
记性挺一般的,现在就只记起6个问题。
第一个问题,问我对django框架的理解,当时我随口就说框架基于MVC模式。M表示models,models模块用来做数据库的表结构设计;V表示views,views模块用来写处理前端的POST/GET请求。C表示Control,用来…… so, 懵比了。面试后再想想,其实django是基于MTV模式~_~,竟然出如此低级的错误……第二个问题是问我了解django的queryset吗? 听到queryset很熟悉,但就是想不起来? 然后我问面试官queryset是python的一个模块吗? 面试官给了点提示: 数据操作。恍然大悟,不就是django的ORM操作嘛。之前过滤数据时,打印出数据对象,其实数据对象就是一个queryset的集合。
第三个问题是问我web聊天室的内容。先问我有没有用开源的一些框架,开源框架??又懵比了,还好,突然想起上次写web聊天室总结时,有园友评论 “AJax这种方式不好。推荐一个PHP后端框架的” 才反应过来,就回答没有,从底层数据表结构开始设计开发。
接下来问我如何管理好友还有Group表的。这个问题当时没准备好,项目创建的表结构忘记了……所以,回答得很差(自我感觉)。回来重新看了下表结构。
管理好友,其实我是在UserProfile用户表里面创建一个friends字段,这样你在admin后台就可以选择好友了。但你的好友其实也是在UserProfile表里面的(也是用户),所以这里用到了自关联,UserProfile表与UserProfile表关联。
# for web qq # 一个用户可以有多个好友(自关联), 可以为空 # 你是我的好友,那我就是你的好友(django默认),如:QQ ;你是我的粉丝,但我不是你是粉丝,可上openstack搜解决方案,如:webo friends = models.ManyToManyField("self", related_name="my_friends", blank=True)
前端可通过如下代码展示当前登陆用户的好友列表
{% for friend in request.user.userprofile.friends.select_related %} { { friend.name }}{% endfor %}
至于管理群的话,额,群有群主,管理员和群成员,它们都是用户,所以都要与UserProfile表关联。WebGroup群表如下。一个群有多个管理员,一个管理员用户可对应多个群,所以是多对多关联。其它略……
# 群聊的表class WebGroup(models.Model): name = models.CharField(max_length=64) # 群名 brief = models.CharField(max_length=255, blank=True) # 群介绍,可为空 owner = models.ForeignKey(UserProfile) # 群主 # 下面这句代码如果再加上null=True,会曝错 # webchat.WebGroup.admins: (fields.W340) null has no effect on ManyToManyField. admins = models.ManyToManyField(UserProfile, blank=True, related_name="group_admins") # 'WebGroup.admins' clashes with reverse accessor for 'WebGroup.members'. # HINT: Add or change a related_name argument to the definition for 'WebGroup.admins' or 'WebGroup.members'. # 只要涉及到同一张表的多个字段关联同一张表,就需要加个related_name members = models.ManyToManyField(UserProfile, blank=True, related_name="group_members") # 群成员 max_members = models.IntegerField(default=200) # 默认最大群人数为200 def __str__(self): return self.name
前端展示群列表,看到没有,前面给群表的related_name="group_members"用处大大的。这样用户表通过related_name就可以反向关联查出所属的群组。
{% for group in request.user.userprofile.group_members.select_related %} { { group.name }}{% endfor %}
第四个问题问聊天室的聊天记录如何保存。还没实现这个功能,尴尬。目前一刷新,聊天数据就没了,嗯,没了……
最后一个问题,是问我如何管理session. session有听过,浏览器与服务端是短连接,用户通过session与服务端保持会话跟踪。但是说到session管理,就……不会了。面试官也是挺好人的,跟我讲了一下session管理,比如用户多了,后台的session肯定也很多,so, what should you do?? 当时对django的session管理机制不明白。只说了一个现象: 我在浏览器登陆A用户,登陆成功后,不退出,此时关闭浏览器。当我再次打开浏览器,进入项目界面时,what the fuck!! A用户已经登陆了。so, 肯定是之前登陆的session浏览器没有清除。
所以晚上回来专门去查了下django的session管理。
存取cookies
读取cookies很简单,因为读取cookies可以使用HttpResquest,每一个HttpResquest对象都有一个COOKIES对象,可以用它读取任何浏览器发送给视图的cookies。
因为每个视图函数的第一个参数都是request,其实它就是一个HtppResquest对象,所以直接使用request.COOKIES读取cookies就好。
写COOKIES就使用HttpResquest对象的set_cookie()方法,set_cookie有一些可选参数来指定一些特殊操作。
session操作
开启session(他是通过一个中间件和一个模型来实现的)。
1.编辑MIDDLEWARE_CLASSES,确保里面已经包含了django.contrib.sessions.middleware.SessionMiddleware。
2.确认INSTALLED_APPS,确保里面已经含有一个叫django.contrib.sessions的鬼畜。
其实这两项,一般默认就有了,前提是你的项目是用python manage.py startproject mysite来创建的。
视图中使用session
SessionMiddleware被激活以后,每个视图函数的第一个参数request(也就是HttpResquest对象)都有一个session属性,它和cookie一样,也是个字典型的对象,可以像使用普通字典那样使用。
如果SESSION_EXPIRE_AT_BROWSER_CLOSE设置为false,那么cookie在浏览器中保存周期是SESSION_COOKIE_AGE秒。如果设置为true,那么关闭浏览器时候,就会失效。
django有四中session实现方式
Django把session存储在哪里?
Session在服务器存储的地点可以设置,分别有:数据库、缓存、文件、cookie。
Session什么时候被保存?
默认情况下,Session被修改的时候才会被保存到数据库。除非我们将 SESSION_SAVE_EVERY_REQUEST设置为True,这样每一次请求Django都会保存session。
保存在数据库中的Session什么时候会被清除?
Django不做清除的工作,开发人员得自己干。意味着必须有某种机制保证数据库中超时的Session会被删除。
如何让浏览器在关闭时删除session?
我们希望浏览器关闭时删除session,这样用户重新打开浏览器的时候就要重新登录。Django官方文档的作法是将设置为True。可以修改Django中session的过期时间(SESSION_COOKIE_AGE,默认为2周),将其修改为半小时或其它时间,每当用户访问网站的时候,重新设置过期时间为SESSION_COOKIE_AGE(可以在中间件中实现),例如:
request.session.set_expiry(10)
这样当用户每次访问网站,session过期时间都会重新设置,当用户超过该时间没有访问网站时,session就过期了。
另外,考虑在客户端加入javascript脚本,使得用户在关闭浏览器的同时,向服务器发送注销请求,服务器端将session也同时注销掉。
数据库的Session什么时候被删除?
Django并不会删除数据库的sission数据。得开发人员自己来删除。
目前只是将设置为True,这样浏览器关闭时删除session。
接下来会学习中间件的知识……
更多关于session管理: ,英文看起来挺吃力~_~