django restful framework 做基于field的权限控制

原因

由于开发需要,需要将机器展示页面分为两种:低权限账户可以查看普通机器的基本信息,但是不能查看密码;高权限账户可以查看所有的信息(包括所有的机器,以及所有机器的账号密码等敏感信息)

实现

系统用Django + DRF编写,查看文档后和Stack Overflow发现可以通过给不同权限的用户展示不同的视图/serializer来实现,找到了如下方法:

在DRF的view基类中有def get_serializer_class(self)方法,将其重写即可根据当前用户的权限来切换serializer:

1
2
3
4
def get_serializer_class(self):
if self.request.user.has_perm("www.saw_pass"):
return SuperSerializer
return IPSerializer

这里写了两个Serializer,分别对应不同权限返回的数据,然后在低权限Serializer中确认好只返回哪些字段即可

推广

此法同样可以用于在用户不同状态返回不同数据、反爬虫等方面

不足

仍然没有将基于field的权限控制脱离代码

django-jet 使用DateRangeFilter 报importError的解决方法

今天在编程时,需要给Django Admin加一个DateRange的list_filter,发现daterange与已安装的jet主题不兼容(不显示),查阅jet文档后发现jet处理了兼容问题:from jet.filters import DateRangeFilter

然而,我在加入上述代码后,报出了如下错误:

1
2
from jet.filters import DateRangeFilter
ImportError: cannot import name 'DateRangeFilter'

搜索了jet的github源码,找到如下解决方案:

1
2
3
4
5
6
7
8
# 将from jet.filters import DateRangeFilter 替换为:
from rangefilter.filter import DateRangeFilter

class MyUserAdmin(UserAdmin):
...
list_filter = (
('date_joined', DateRangeFilter),
)

引用:
https://github.com/geex-arts/django-jet/blob/552191c5be551741b3349aa104c92435702f62e5/docs/filters.rst

Django Admin add "Export to Excel" action

  • It’s a convinent action to export excel with your data in Django
  • require pandas and xlwt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import pandas as pd

# Register your models here.
def export_to_excel(modeladmin, request, queryset):
response = HttpResponse(content_type="application/xls")
data = serializers.serialize("json", queryset, stream=response)
data = json.loads(data.decode("utf-8"))
data = [i['fields'] for i in data]
data = pd.DataFrame(data)
data = data.fillna('空')
data.to_excel("./tmp.xls")
test_file = open('./tmp.xls', 'rb')
response = HttpResponse(content=test_file)
response['Content-Type'] = 'application/xls'
response['Content-Disposition'] = 'attachment; filename="%s.xls"' \
% 'export'
return response

class Export(admin.ModelAdmin):
actions = (export_to_excel,)

用nginx+python快速克隆网站

原由

之前接了一个仿制网站+特定页面更改的项目,原网站竟然用的是IE6

在用各种页面下载工具仍然无法完整的复制网站后,突然想出了另一种思路: 用nginx反向代理原网站,然后只修改特定的页面是否可行?

在进行试验后,发现是可行的

方案

1.nginx配置样例如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
location /queryHistory.asp {   # 需要定制的页面
rewrite ^/(.*)$ /$1 break;
proxy_pass http://127.0.0.1:8000/; # 这里用的是django
}
location /static {
rewrite ^/(.*)$ /$1 break;
proxy_pass http://127.0.0.1:8000/;
}

location / {
rewrite ^/(.*)$ /$1 break;
#access_log off; # 开启记录日志
proxy_set_header X-Forwarded-For $remote_addr;
proxy_pass http:/xxx.xxx.xxx.xxx:8080; # 在这里转发原网站
access_log /var/log/nginx/access.log;

}
  1. Django配置好url,同上方/queryHistory.asp 一样,然后按需求更改
    * 注意,重写的url配置要放在转发的原网站上方

3.对于template和staticfile的问题,完全不需要额外去找原网站的staticfile,因为nginx会自动反向代理到开发机上

展望

这套方法目前已经作为成为了我仿制网站的基本流程,还需要做的就是准备研究一下nginx的缓存功能,通过几次对网站的访问,将缓存用nginx完整的『抓』下来,实现不依赖原网站的仿制网站

【踩坑】dracut_initqueue【599】: Warning: Could not boot

用pd虚拟机安装CentOS时,出现了如下错误:
dracut_initqueue[599]: Warning: Could not boot

原因是由于linux安装程序没有识别设备造成的

解决方案:

在选择系统界面按下TAB,将stage2=后面改成/dev/sdx(x为你的u盘设备名),在这里由于pd是将iso作为光盘安装的,因此改成/dev/cdrom

【踩坑】 sudo: sorry, you must have a tty to run sudo (附解决方案)

最近在做一个Linux软件的打包成为iso发行的流程,大体是这样的:

1.准备好软件安装的相关脚本
2.编写spec文件,通过rpmbuild来将其打包为yum
3.测试yum安装通过后,将其写入一个Linux镜像安装文件夹的Packages并重新生成repo
4.打包iso,虚拟机安装测试

我在这里卡在了第4步上:文件成功的安装并复制到了虚拟机,但是执行MySQL初始化的脚本却出现了错误:脚本不执行,而在启动后手动执行时,正常安装

由于错误难以收集,我将初始化脚本写入了/etc/rc.local ,准备用重启后自动安装的方式来『绕过』

然而这样同样失败了,经过在rc.local 中写入:sh init_mysql.sh 2>/root/err后,才发现出现了这样的一行错误:
sudo: sorry, you must have a tty to run sudo
原来安装mysql的代码中由于需要切换到mysql用户执行,在导入sql文件时用了sudo执行,而不管是在安装Linux时还是在启动rc.local的过程中,都不算在终端执行

解决方案:

1.去除sodo 用root用户执行权限
2.修改 /etc/sudoers ,将 Default requiretty这一行加上#注释