要么改变世界,要么适应世界

Django一些学习笔记

2024-03-09 22:00:56
69
目录

模型转dict

# 获取所有的Dataset对象的QuerySet
dataset_all = Dataset.objects.all()
# 使用model_to_dict将每个对象转换为字典
dataset_all_dicts = [model_to_dict(obj) for obj in dataset_all]

调用model_to_dict的时候我们还可以指定包含或者排除的字段:

model_to_dict(obj, fields=["a", "b"], exclude=["c"])

如果我们还想在转换过程添加其他比较复杂的转换,我们可以直接手写一个,例如我想把时间类型的属性同时转换成人类可阅读的字符串和时间戳:

# 自定义的用于转dict,添加一个将时间转为时间戳的功能
def my_model_to_dict(instance, fields=None, exclude=None):
    opts = instance._meta
    data = {}
    for f in opts.fields + opts.many_to_many:
        if fields and f.name not in fields:
            continue
        if exclude and f.name in exclude:
            continue
        if isinstance(f, DateTimeField):
            value = f.value_from_object(instance).timestamp()
            data[f"{f.name}_timestamp"] = value
        data[f.name] = f.value_from_object(instance)
    return data

聚合

有时候我们需要根据一组对象聚合后才能得到我们想要的结果,例如有一批学生成绩,我们要获取到最值,可以通过聚合操作完成:

max_score = score_objects.aggregate(max_score=Max("filed_name"))['max_score']
min_score = score_objects.aggregate(Min("filed_name"))

推荐使用第一行,因为聚合时候,如果我们不指定新的一个新的属性名(也称“新列”),那么Django会默认给新列一个新的属性名,假如最大值是99,最小值是60,则

max_score = 99
min_score = { "filed_name__min" : 60 }

去重

Model.objects.values("distinct_filed").distinct().all()

分组并组内运算

# 根据 IP 分组,然后计算组内的最早最晚时间
result = Model.objects.values('ip').annotate(
    latest_time=Max('create_time'),
    earliest_time=Min('create_time')
).values('ip', 'latest_time', 'earliest_time').all()

返回文件(以返回压缩文件为例)

# 打开zip文件,并读取其内容
with open(zip_file_path, 'rb') as zip_file:
    response = HttpResponse(zip_file.read(), content_type='application/zip')
# 设置响应头,指定文件名
response['Content-Disposition'] = f'attachment; filename={os.path.basename(zip_file_path)}'
return response

读取客户端上传的文件

uploaded_file = request.FILES.get("datasetFile")
# 创建一个临时目录用于存放解压缩后的文件
temp_dir = os.path.join('data', 'temp_dir')
os.makedirs(temp_dir, exist_ok=True)

# 将上传的文件保存到临时目录
uploaded_file_path = os.path.join(temp_dir, uploaded_file.name)
with open(uploaded_file_path, 'wb') as destination:
    for chunk in uploaded_file.chunks():
        destination.write(chunk)

事务

通常有两种用法:

一种是加在view函数上面,这样整个reuqest都会在事务中:

@transaction.atomic
def hello_view(request):
    # 数据库操作
    pass

也可以在需要访问数据库的代码处使用事务包裹 ,实现精准把控:

def hello_view(request):
    
    with transaction.atomic():
    # 数据库操作    
        pass

未完待续 ,持续更新

历史评论
开始评论