Python WEB开发

1、Python语言

2、开发环境

Pycharm 2018.1.4永久版

导入jar包;
pycharm.vmoptions and pycharm64.vmoptions分别插入:
-javaagent:/opt/pycharm-2018.1.4/bin/JetbrainsCrack-3.1-release-enc.jar


虚拟环境
# 下载virtualenv
pip3 install virtualenv
# 创建一个名为venv的虚拟环境,参数--no-site-packages已安装好的python环境中的三方包不会被继承过来
virtualenv --no-site-packages venv
# 继承所有库
virtualenv --system-site-packages VENV
# 指定python版本
virtualenv -p python3 Venv3
# 进入虚拟环境
source venv/bin/activate
# 退出当前虚拟环境
deactivate

Windows系统安装virtualenv失败,类似setuptools pip wheel failed with error code 2,可能是setuptools和virtualenv版本导致
解决思路:升级后再创建

pip install setuptools
pip install --upgrade setuptools
pip install virtualenv
pip install --upgrade virtualenv

环境变量
import os
import sys
sys.path # 打印环境变量
sys.argv[2] # 取值
os.system('dir') # 执行命令显示在屏幕,不保存结果
os.popen('dir').read() # 保存
os.mkdir('new_dir')

3、开发框架

Django

查询
from functools import reduce

lst = [Q(question_text__contains='you'), Q(question_text__contains='who')]

# OR
>>> Question.objects.filter(reduce(operator.or_, lst))
[<Question: what are you doing>, <Question: what is wrong with you>, <Question: who are you>, <Question: who am i>]

# AND
>>> Question.objects.filter(reduce(operator.and_, lst))
[<Question: who are you>]


>>> from functools import reduce
>>> reduce(lambda x, y: x + y, [1,2,3,4,5,6,7,8])
36

F查询
class StockHelper(object):
    @classmethod
    def update_stock(cls, params):
        specification_id = params['specification_id']
        amount = params['amount']
        update = params['update']
        spe = Specification.objects.filter(specification_id=specification_id, is_deleted=False)
        if not spe:
            return
        if update == 'reduce':
            spe.update(stock=F('stock') - amount)
        if update == 'restore':
            spe.update(stock=F('stock') + amount)

Q查询
class CouponParkingsView(View):
    @client_required()
    def get(self, request):
        flag, data = validate_form(CouponParkingsForm, request.GET)
        if not flag:
            return HttpJsonResponse({
                "message": "Validation Failed",
                "errors": data
            }, status=422)
        q = Q(is_deleted=False)
        q &= Q(status=1)
        q &= ~Q(parking_relation=None)
        q &= ~Q(parking_relation__park_id='')
        q &= ~Q(parking_kind=2)
        q &= ~Q(lon='')
        if data['parking_name']:
            q &= Q(parking_name__icontains=data['parking_name'])
        if data['area_type']:
            q &= Q(area_type=data['area_type'])
        if data['parking_ids']:
            q &= Q(parking_relation__park_id__in=data['parking_ids'].split(','))
        parkings = Parking.objects.filter(q).distinct()
        page_num = data['page_num']
        page_size = data['page_size']
        queryset = parkings[page_size * (page_num - 1):(page_num * page_size + 1)]
        datas = [_.coupon_info() for _ in queryset[:page_size]]
        if len(datas) == 0:
            return http_response([])
        response = HttpJsonResponse(data=datas, status=200)
        if len(queryset) > page_size:
            params = 'page_num=%d&page_size=%d' % (
                data['page_num'] + 1, data['page_size'])
            if data["parking_name"]:
                params = params + '&parking_name=%s' % urllib.parse.quote(data["parking_name"])
            if data["parking_ids"]:
                params = params + '&parking_ids=%s' % data["parking_ids"]
            if data["area_type"]:
                params = params + '&area_type=%s' % data["area_type"]
            response['Link'] = r'<%s%s?%s>; rel="next"' % (
                get_local_host(request), request.path, params
            )
        return response

运算
100 // 3 = 33 # 向下取整
100 % 3 = 1

浮点数

IEEE754标准规定,浮点数由“符号”、“指数”和“尾数”3部分构成:
在这里插入图片描述这里可以得出一个结论:任意一个int值(二进制表示),只要存在这样的序列:从最低位开始找到第一个1,然后从这个1向高位数移动24位停下,如果更高的位上不再有1,那么该int值即可被float精确表示,否则就不行。简单说,就是第一个1开始到最后一个1为止的总位数超过24,那么该int值就不能被float类型精确表示

由于浮点数在计算机中实际是以二进制保存的,有些数不精确。
比如说: 0.1是十进制,转化为二进制后它是个无限循环的数:
0.00011001100110011001100110011001100110011001100110011001100

>>>0.1 + 0.2
0.30000000000000004

解决该问题的几种方法:

  • round函数
round(0.1+0.2)
0.3
  • Decimal函数
Decimal('0.1') + Decimal('0.2')
0.3

单点登录
from django.contrib import auth
from django.contrib.auth.hashers import make_password
 
user = auth.authenticate(username=username, password=password)  # 校验用户密码
if user:  # 如果密码正确
    # 通过存储的原始密码生成新的密码
    user.password = make_password(user.real_password)
    # 更新密码,更新后用户仍然可以使用同样的密码登陆,但是数据库中的加密后的密码已经改变,这样所有终端的登陆状态就会失效
    user.save()
    # 所有终端的登陆状态失效后在当前终端设置cookie和session,使用户进入登陆状态
    auth.login(request, user)

SimpleListField 校验列表
class SimpleListField(Field):
    default_error_messages = {
        'invalid': ugettext_lazy('Enter a valid value.'),
    }

    def __init__(self, inner_field=None, inner_form=None,
                 max_length=None, min_length=None, *args, **kwargs):
        self.inner_field = inner_field
        self.inner_form = inner_form
        self.max_length = max_length
        self.min_length = min_length
        super(SimpleListField, self).__init__(*args, **kwargs)

        if inner_field and not isinstance(inner_field, Field):
            raise ValueError('inner_field invalid')
        if inner_form and not issubclass(inner_form, Form):
            raise ValueError('inner_form invalid')
        if not inner_field and not inner_form:
            raise ValueError('inner_field or inner_form must has one')
        if min_length is not None:
            self.validators.append(validators.MinLengthValidator(min_length))
        if max_length is not None:
            self.validators.append(validators.MaxLengthValidator(max_length))

    def to_python(self, value):
        if value in validators.EMPTY_VALUES:
            return value
        if (type(value) is six.binary_type) or (type(value) is six.text_type):
            try:
                value = json.loads(value)
            except ValueError:
                pass
        if type(value) is not list:
            raise ValidationError(self.error_messages['invalid'])
        new_value = []
        if self.inner_field:
            for one in value:
                try:
                    new_value.append(self.inner_field.clean(one))
                except ValidationError:
                    raise ValidationError(self.error_messages['invalid'])
        elif self.inner_form:
            for one in value:
                _form = self.inner_form(one)
                if not _form.is_valid():
                    raise ValidationError(self.error_messages['invalid'])
                new_value.append(_form.cleaned_data)
        return new_value

form 表单校验
def validate_form(form_class, data):
    form = form_class(data)
    if form.is_valid():
        return True, form.cleaned_data
    errors = []
    for key, field in form.declared_fields.items():
        if field.required and key not in data:
            errors.append({"field": key, "code": "missing_field"})
        elif key in form.errors:
            errors.append({"field": key, "code": "invalid"})
    return False, errors

get 接口列表分页
class CouponCompaniesView(View):
    @client_required()
    def get(self, request):
        """
        优惠券平台获取企业列表
        :param request:
        :return:
        """
        flag, data = validate_form(CouponCompaniesForm, request.GET)
        if not flag:
            return HttpJsonResponse({
                "message": "Validation Failed",
                "errors": data
            }, status=422)
        q = Q(reviewed_status=2, is_deleted=False)
        if data['company_type']:
            companies = Company.objects.filter(q, company_type__contains=str(data['company_type']))
        else:
            companies = Company.objects.filter(q)
        page_num = data['page_num']
        page_size = data['page_size']
        queryset = companies[page_size * (page_num - 1):(page_num * page_size + 1)]
        datas = [_.coupon_info() for _ in queryset[:page_size]]
        response = HttpJsonResponse(data=datas, status=200)
        if len(queryset) > page_size:
            params = 'page_num=%d&page_size=%d' % (data['page_num'] + 1, data['page_size'])
            if data["company_type"]:
                params = params + '&company_type=%s' % data["company_type"]
            response['Link'] = r'<%s%s?%s>; rel="next"' % (
                get_local_host(request), request.path, params
            )
        return response

log 处理
  • 带参数: request.get_full_path()
  • 不带参数: request.path
  • request.build_absolute_uri

M2M
from django.db import models
# 主表
class Author(models.Model):
    first_name = models.CharField(max_length=30)
    last_name = models.CharField(max_length=40)
    email = models.EmailField()
 
 
# 从表
class Book(models.Model):
    title = models.CharField(max_length=200)
    authors = models.ManyToManyField(Author)
 
# 从表查主表
b = Book.objects.get(id=50)
b.authors.all()
b.authors.filter(first_name='Adam')
 
# 主表查从表
a = Author.objects.get(id=1)
a.book_set.all()
 
# 添加对象
a = Author.objects.get(id=1)
b = Book.objects.get(id=50)
b.authors.add(a)
 
# 删除对象
a = Author.objects.get(id=1) 
b = Book.objects.get(id=50) 
b.authors.remove(a) 或者 b.authors.filter(id=1).delete()

手机号码脱敏
a = "13012345678"
1) phone = a.replace(a[3:6], "****")
2) phone = a[:3] + "****" + a[7:]

加密
import base64
import hashlib

client_id = input("Input the client-id: ")
client_secret = input("Input the client-secret: ")

md5 = hashlib.md5(("%s%s" % (client_id, client_secret)).encode()).hexdigest()
base = base64.b64encode(("%s:%s" % (client_id, client_secret)).encode()).decode()

update()
u = UserInfo.objects.get(user__username='liuyuan1')
info = dict()
info['telephone'] = '13022223366'
info['address'] = '000000000000'
info['contacts'] = '000000000'
info['create_user'] = u
info['delete_user'] = u
Merchant.objects.filter(merchant_id='a4a8446ed2d811e9b0cb309c23b26d94').update(**info)
Merchant.objects.update_or_create(merchant_id='a4a8446ed2d811e9b0cb309c23b26d94', defaults=info)

项目打包
v=1.4.0
team_name=zmy
project_name=comment_server
cat .docker/environment-r | xargs -I {} echo ""ENV {}"" >> .docker/Dockerfile
image_name=docker.uucin.com/$team_name/$project_name:r$v
docker build -f .docker/Dockerfile --tag $image_name .
docker push $image_name

Integer
integer_field_ranges = {
    'SmallIntegerField': (-32768, 32767),
    'IntegerField': (-2147483648, 2147483647),
    'BigIntegerField': (-9223372036854775808, 9223372036854775807),
    'PositiveSmallIntegerField': (0, 32767),
    'PositiveIntegerField': (0, 2147483647),
  }

Flask

4、使用工具

Git

git pull 更新代码;
git push --tags 推tag至gitbucket;
git tag -d v1.20.0 删除本地tag;
git push origin :refs/tags/v1.20.0 删除远端tag;
git clone + URL 克隆代码;
git checkout master 切换分支;
git branch 查看分支;
git config --global credential.helper store 设置git默认密码;

git rm company.py
git commit -m “remove company.py”

Docker

概念及组成
DockerClient客户端
Docker Daemon守护进程
Docker Image镜像
DockerContainer容器

常用命令

docker ps 查看所有容器;
docker images 查看所有镜像;
docker ps -a 查看所有容器(含未运行);
docker commit [options] CONTAINER [repository [:Tag]]
从container创建新的image
-a 提交的镜像作者 -c 使用Dockerfile指令创建镜像
-m 提交时的说明文字 -p commit时将容器暂停;"
docker logs -f ID 查看日志;
docker exec -it ID bash 进入容器;
docker restart ID 重启服务器;
docker stop/start container 停止/启动容器;
docker rm container 删除容器;
docker rmi images 删除镜像;
docker image ls -f dangling=true & docker image prune

docke-compose -f .docker/docker-compose-d.yml down
docke-compose -f .docker/docker-compose-d.yml up -d --build


Terminal

scp /liuxin/usr/local ssh root@10.1.50.100:/usr/local 复制文件到服务器
ctrl + a 移动到本行首
ctrl + e 移动到本行末
ctrl + u 删除光标前所有
ctrl + k 删除光标后所有
ctrl + w 向左删除单词
ctrl + & 恢复删除的字符
ctrl + ←上一个单词开头
ctrl + →下一个单词结尾
ls -a 显示所有文件,包含隐藏文件
ls -ah 查看隐藏文件"
chmod 命令:
u:文件的拥有者; g: 与该文件的拥有者属于同一个群体;o:表示其他以外的人;a:这三者都是 User/Group/Other
+/-/=:增加/取消/唯一设定权限
r:可读;w:可写;x:可执行;X:表示只有当该文件是个子目录或者该文件已经被设定过为可执行
-R : 对目前目录下的所有文件与子目录进行相同的权限变更(即以递回的方式逐个变更)
[root@localhost ~]# chmod 700 /mnt/fileA注:仅把fileA目录的权限设置为700
[root@localhost ~]# chmod -R 744 /mnt/fileA注:表示将整个/mnt/fileA目录与其中的文件和子目录的权限都设置为744
-v : 显示权限变更的详细资料
例子:chmod ugo+r file1.txt/chmod a+r file1.txt 将file1设置为所有人皆可读取
chmod ug+w, o-w file1.txt, file2.txt 将文件 file1.txt 与 file2.txt 设为该文件拥有者,与其所属同一个群体者可写入,但其他以外的人则不可写入
chmod u+x ex1.py 将 ex1.py 设定为只有该文件拥有者可以执行
chmod a=rwx file 等价于 chmod 777 file
chmod ug=rwx, o=x file 等价于 chmod 771 file
若用chmod 4755 filename可使此程序具有root的权限
所有权及所属用户组也能修改,和设置权限类似,用户可以通过图形界面来设置,或执行chown命令来修改"
创建文档:gitbook
ssh root@10.1.50.100
cd /etc/nginx/conf.d/uudocs
cp shenyang_itgs_server.conf base-apollo.conf
vim base-apollo.conf

celery

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值