python - 我怎样才能让不同的客户端每次加载唯一的行(不重叠),而不进行用户登录 session ?

标签 python django database

我有一个用 Django 构建的应用程序,其目的是允许用户自定义数据库的特定列。这是当前的基本功能:

  • 从 table_a 中选择 30 个不同的行。
  • 一次一行,让用户编辑特定字段。
  • 每次编辑后,将该行发送到 table_b,以便在更新 table_a 之前再次检索以进行最终检查。
  • 这批30行完成并存入table_b后,从table_b中全部取出来进行检查。
  • 按确认按钮以使用检查过的编辑更新 table_b。

以上所有工作都很好,不是问题所在。问题在于,在最初批量选择 30 行之后,另一个客户端也可能会选择这 30 行中的部分(或全部)作为他们的批处理。

这个问题与上面详述的应用程序的结构无关,而是关于如何集成以防止客户端在当前应用程序架构下处理相同的行。但是,如果您想拆开它的构建方式,请同时解释如何按照我的要求进行操作。特别是如果这对我的需要是必要的。

下面是我正在使用的四个 views.py 函数(从 table_a 中选择 30 个,将单独的行发送到 table_b,从 table_b 中选择所有进行检查,发送所有 30 个检查以更新 table_a)。

@csrf_protect
def get_from_fim_table(request):
    if request.GET:
        if 'drugList' in request.GET:
            # retrieve fims from database
            fims = Fim.objects.select_for_update().filter(drug_type='').filter(verify=True).exclude(crib_name='')[:int(request.GET.get('numberOfDrugs'))]
            untyped_drugs = [fim.crib_name for fim in fims]
            urls = [fim.drug_type for fim in fims]
            number_of_drugs_in_batch = len(fims)
            number_of_drugs_left = len(Fim.objects.filter(drug_type='').filter(verify=True).exclude(crib_name='').distinct('crib_name'))
            return HttpResponse(json.dumps({'data' : [untyped_drugs, urls, number_of_drugs_in_batch, number_of_drugs_left]}), content_type='application/json')
    return HttpResponse(json.dumps({'data' : 'Error with request.GET'}), content_type='application/json')


@csrf_protect
def send_to_temporary_table(request):
    if request.POST:
        if 'drug_name' in request.POST and 'drug_type' in request.POST:
            drug_name = json.loads(request.POST['drug_name'])
            drug_type = json.loads(request.POST['drug_type'])

            new_temp_drug = TypesToVerify.create(drug_name, drug_type)
            new_temp_drug.save()

            return HttpResponse(json.dumps({'data' : 'Successfully stored drug and type into types_to_verify table.'}))


@csrf_protect
def get_from_temporary_table(request):
    if request.GET:
        unverified_drugs = [x.crib_name for x in TypesToVerify.objects.all()]
        unverified_drug_types = [x.drug_type for x in TypesToVerify.objects.all()]
        return HttpResponse(json.dumps({'data' : [unverified_drugs, unverified_drug_types]}), content_type='application/json')
    return HttpResponse(json.dumps({'data' : 'Error with request.GET'}), content_type='application/json')


@csrf_protect
def send_to_fim_table(request):
    if request.POST:
        if 'drug_list' in request.POST and 'type_list' in request.POST:
            drug_list = json.loads(request.POST['drug_list'])
            type_list = json.loads(request.POST['type_list'])

            for i in range(len(drug_list)):
                fims = Fim.objects.filter(verify=True).filter(crib_name=drug_list[i])
                for fim in fims:
                    fim.drug_type = type_list[i]
                    print('{} was assigned the type {}.'.format(drug_list[i], type_list[i]))
                    fim.save()

            # delete all rows in types_to_verify
            TypesToVerify.objects.all().delete()
            print('\nCleaned out types_to_verify table for next batch.\n')

            return HttpResponse(json.dumps({'data' : 'Successfully assigned types.'}))
        return HttpResponse(json.dumps({'data' : 'There was an error getting the request on the server side.'}))

谢谢!

最佳答案

在将数据库中的行分配给用户后,您需要锁定这些行,然后在用户使用完这些行后将其解锁。这可以通过向模型添加一个 claimed 字段来实现,但是如果用户没有完全完成他们的编辑怎么办?当用户的 session 结束时,您可以“取消声明”所有这些对象,但这似乎有点麻烦。

与其翻转 claimed 开关,我认为您应该向模型添加一个 assigned_at DateTimeField。当用户从数据库中获取他们的 30 行时,保存对象以更新他们的 assigned_at 字段(如果您在创建模型时设置了 auto_now=True)。

然后,当您将行分配给用户时,通过检查上次分配是否超过 x 时间(直到用户“次out”并释放行?)。这可以使用 range() 来完成.

不过,您在这里需要小心。如果我们的第一个用户在超时后返回并尝试继续编辑怎么办?您可以通过实际将用户分配给该行以及向模型添加外键来避免这种情况。生成“无人认领”对象的列表后,保存您分配给处理该行的用户 (model.owner = request.user)。然后,当您收到编辑该行的请求时,验证发送请求的用户实际上“拥有”该行:

if model.owner != request.user:
     return HttpResponse("You can't do that!", status=403)

关于python - 我怎样才能让不同的客户端每次加载唯一的行(不重叠),而不进行用户登录 session ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42936780/

相关文章:

python - 如何使用 python opencv 去除这些图片中的阴影?

json - 在 ChoiceField 中返回 display_name

django - 如何在 Django 中预取聚合的@property?

mysql - 如何查询以日期命名的一系列表

python - 使用 ftplib 时出错

python - 避免在 numba 优化函数中使用 str()

python - 从 numpy loadtxt() 获取日期列

django - docker-为开发和生产组合相同的配置,但仅在开发中启用主机和容器之间的代码共享

php - 如何处理数据库中项目列表的 "order"(php)

database - PostgreSQL : How to create two instances in same window machine?