陌陌实现过程

User

Django 内置form表单验证(只适用于网页开发,不适用于前后端分离的ajax传输)

request.META request请求头 (包含请求头所有内容)
request.META[‘REMPTE_ADDR’] 访问者IP(可用于IP禁止)
request.META[‘HTTP_USER_AGENT’] 用户代理

头像上传
使用Django内置chunks()分片上传
生产环境下Django不擅长管理静态文件(通常会使用):
使用Nginx 部署静态文件
CDN(内容分发网络)
云存储(亚马逊S3服务,阿里云oss,七牛云)

  • 文件上传七牛云
    1.在官网新建一个bucket
    2.安装pip install qiniu
    3.配置文件

celery 异步上传头像(我们可以使用celery异步框架,我们可以把耗时的任务扔到后台,而前端给用户立即返回,待用户需要查看结果时,点击查看即可,并且可以随时看到任务执行的状态。)
celery worker -A tasks --loglevel=info #启动celery
func.delay() #开启异步任务

Social

​ 推荐接口(将所有符合要求的用户显示出来,

​ 建立滑动记录关系表

uid           sid           mark
1	56	like/superlike
1	88	like/superlike
56	1	like/superlike	#互相喜欢加为好友

建立好友关系表
uid	fid
1	56
1	88
56	1
88  1
————————————————
uid1	uid2
1  		56
1  		88
#(uid1,uid2进行比较,小的放前面。
#第二次传进来,也只会有一条记录)

自定义管理器:
Usre.objects objects本身就是一个manager,我们可以自定义个类,继承models.Manager,就可以通过User.objects.方法名,调用里面的函数

#判断类型:
isinstance(a,int) ==>> type(a)==int
True


中间件:MTV
	运行流程:
	        WSGI(封装报文)	          		WSGI
	          |	(产生request对象)             |
	process_request						process_response
	          |	(匹配url)	            		|
	process_view	       		process_template_response
	          |			             			  |
	      view			      					templates
	          \			          				 /
	             \			        		 /
			process_exception(任意地方报错,皆可捕获)

自定义中间件来捕获错误异常:
自定义一个类,继承MiddlewareMixin,使用process_exception方法会自动捕获出现的异常。便可对异常进行处理。

两种抛出错误的方法:

方法一:定义一个类继承于Except

class LogicException(Exception):

 '''
	自定义逻辑异常类
	调用者通过参数,传递错误码

  '''
 def __init__(self,code):
   		 self.code = code



方法二:

通过type动态创建类:
Dog(变量) = type(‘类名’,(继承于,),{‘属性’:‘大黄’,‘方法’:‘run’})
实例化: Dog.属性
>>>‘大黄’
Dog.方法
>>>run

#创建一个基类
def LogicError(Except):
code=None

def gen_logic_error(name,code):
return type(name,(LogicError,),{‘code’:code})
实例化:SidError = gen_logic_error(‘SidError’,3001)


​	
​	Json中文输出Ascall码问题
​	Json.dumps(d,ensure_ascii=False)#ensur_ascii是否转为Ascall码

​	

反悔接口:
通过创建时间,撤销上一次操作,并删除建立的好友关系
反悔次数:(每日三次)
在缓存中定义一个字段,可以设置有效期,又可以做次数加减

好友列表:
查询Friend表中uid1=我的,或者uid2=我的。如果uid1=我,那sid就是我的好友,反之亦如此。

喜欢过我接口:
再滑动记录表中查找sid=我的,Mark标记为like或者superlike,并排除好友列表现有的好友,显示出来

VIP

RBAC 权限管理模型

会员表
	name	level	price
	   1	  0	  0
	   2	  1	  5
	   3	  2	 10
权限表
id	name 		decription
1	no-ad		去广告
2	superlike		超级喜欢
3	rewind		反悔

会员-权限表
vip_id	perission_id
    2	        1
    2	        2
    3	        1
    3	        2
    3	        3


利用后台冷启动插入数据

在用户表加入个字段,关联会员等级

装饰器:

1.不带参数的装饰器(两层)
def check(func):
      def wapper():
             a=fun()
	if a<0:
	   return a
       return wapper

@check
def foo():
     a = random.randint(-10,10)
     return a

2.函数带参数
def check1(func):
      def wapper(a):
             b=fun(a)
	if b<0:
	   return 0
	else:
	   return b
       return wapper

@check1
def foo1(a):
     return a

3.装饰器带参数(三层)

def check2(x):
      def decorator(func):
             def wapper(a):
                   b=fun(a)
	      if b<x:
	           return x
	      else:
	           return b
               return wapper
      return  decorator

@check2
def foo2(a):
     return a

​ 当用户调用VIP才能使用的superlike,rewind,like-me接口时,检查用户的VIP等级,到VIP-permission表中对应的权限。

日志模块:

通过配置日志文件,在process_exception中间件中捕获之后,使用logging模块将其输出。

通过日志统计DAU:

​ 在用户登录之后,输出日志到info.log中,在linux中使用下命令统计

cat info.log |grep 2019-07-26 | awk -F':' '{print $5}' | sort | uniq |wc -l
	grep 2019-07-26 #筛选出当天日志
	awk -F':' '{print $5}' #以 : 切片,打印第五列
	sort    #排序
	uniq    #去重
	wc -l    #统计个数

统计出DAU活跃度最高的前五名用户

 cat info.log |grep 2019-07-26 | awk -F':' '{print $5}' | uniq -c| sort -r  | head -n 5
	uniq -c 去重并显示重复次数
	sort -r  升序(默认降序)
	head -n 5 显示前五个

Linux 三剑客: awk,

缓存:

​ 为个人模块设计缓存,当用户第一次获取个人资料的时候先从缓存获取,如果不存在则访问数据库,从数据库中加入缓存,等第二次第三次获取就可以直接从缓存中获取,从而减少数据库的访问次数。当数据更新时,要立刻更新缓存否则会引发一个问题:
​ 如果缓存中数据还未过期,又更新了数据库的内容,用户获取到的还是更新之前的数据。直到缓存过期,再次从数据库获取。

类的底层架构

In [1]:class A (object): 
   ...:     z  =789 
   ...:     def __init__(self): 
   ...:         self.x = 123 
   ...:         self.y = 456 
   ...:     def foo(self): 
   ...:         return self.x+self.y 
   ...:                                                                         

In [2]: a = A()                                                                 

In [3]: a.foo()                                                                 
Out[3]: 579

In [4]: a.y                                                                     
Out[4]: 456

In [5]: a.x                                                                     
Out[5]: 123

In [6]: A.z                                                                     
Out[6]: 789

#类的底层结构

In [7]: a.__dict__                                                              
Out[7]: {'x': 123, 'y': 456}

In [8]: A.__dict__                                                              
Out[8]: 
mappingproxy({'__dict__': <attribute '__dict__' of 'A' objects>,
              '__doc__': None,
              '__init__': <function __main__.A.__init__(self)>,
              '__module__': '__main__',
              '__weakref__': <attribute '__weakref__' of 'A' objects>,
              'foo': <function __main__.A.foo(self)>,
              'z': 789})



[外链图片转存失败(img-9sT1QrJv-1565107026482)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\1564821813774.png)]

a是类A的实例,通过a可以调用self所带的属性或方法,通过A可以调用非self绑定的属性。也就是说,self.x/self.y绑定在类的实例里,而z只是包含在类中。

动态添加类属性和方法

#动态添加类属性
In [9]: a.z =321

In [10]: a.z                                                                     
Out[10]: 321

In [11]: a.__dict__                                                              
Out[11]: {'x': 123, 'y': 456,'z':321}

#动态添加类方法
In [16]: def bar(self): 
    ...:     return self.x * self.y 
    ...:                                                                        

In [17]: A.bar=bar                                                              

In [18]: A.__dict__                                                             
Out[18]: 
mappingproxy({'__dict__': <attribute '__dict__' of 'A' objects>,
              '__doc__': None,
              '__init__': <function __main__.A.__init__(self)>,
              '__module__': '__main__',
              '__weakref__': <attribute '__weakref__' of 'A' objects>,
              'bar': <function __main__.bar(self)>,
              'foo': <function __main__.A.foo(self)>,
              'z': 789})

In [19]: a.bar()                                                                
Out[19]: 56088



朋友圈模块:

1.拉取动态的方式

动态表Dynamics

iduid动态time
1001text1time
2001text2time
3005text3time
4006text4time
5007text5time
6005text6time
7007text7time

Friend表

iduidfid
1001005
2001006
3001007

friend_list =Friend .objects.filter(id=user.id)

dynamics =Dynamics.object.filter(Uid__in=friend_list).order_by(‘time’)

2.推送动态的方式

当好友001一发送动态,立刻推送给各个好友(插入一条数据)

005 1

006 1

007 1

friend_list = Friend .objects.filter(id=001)

for id in friend_list:

​ Pyq.objects.create(uid=id,Dynamics_id=3)

朋友圈内容表

Pyq

iduidDynamics_id
10051
20061
30071
40052
50062
60072

当005查看朋友圈的时候就有两条动态了

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值