Python 如何使不同的客户端每次加载唯一的行(不重叠),而不进行用户登录会话?

Python 如何使不同的客户端每次加载唯一的行(不重叠),而不进行用户登录会话?,python,django,database,Python,Django,Database,我有一个内置于Django的应用程序,其目的是允许用户自定义数据库的特定列。以下是当前的基本功能: 从表a中选择30个不同的行。 一次一行,让用户编辑特定字段。 每次编辑后,将该行发送到表_b,以便在更新表_a之前再次检索以进行最终检查。 完成30行的批次并存储在表_b中后,从表_b中检索所有行以进行检查。 按下“确认”按钮以使用已检查的编辑更新表_b。 以上所有方法都很好,这不是问题所在。问题是,在初始批处理选择了30行之后,另一个客户机也可能为其批处理选择部分或全部这30行 这个问题不是关于

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

从表a中选择30个不同的行。 一次一行,让用户编辑特定字段。 每次编辑后,将该行发送到表_b,以便在更新表_a之前再次检索以进行最终检查。 完成30行的批次并存储在表_b中后,从表_b中检索所有行以进行检查。 按下“确认”按钮以使用已检查的编辑更新表_b。 以上所有方法都很好,这不是问题所在。问题是,在初始批处理选择了30行之后,另一个客户机也可能为其批处理选择部分或全部这30行

这个问题不是关于上面详述的应用程序的结构,而是关于如何在当前应用程序体系结构下集成客户端,防止客户端在同一行上工作。但如果你想拆开它是如何建造的,也请解释一下如何按照我的要求去做。特别是如果这是我所需要的

下面是我正在使用的四个views.py函数:从表a中选择30,将单个行发送到表b,从表b中选择全部进行检查,将所有30个已检查的发送到更新表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.'}))

谢谢大家!

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

我认为您应该在模型中添加一个指定的_at datetime字段,而不是翻转声明的开关。当用户从数据库中获取30行时,如果在创建模型时将auto_now设置为True,则保存对象以更新其分配的_at字段

然后,当您要将行分配给用户时,通过检查可能声明的行的上一次分配是否早于x时间,筛选出可能声明的行,直到用户超时并释放这些行需要多长时间?。这可以通过使用

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

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

完全适合我。谢谢你的建议。稍后我会用我所做的事情来更新这条评论。太棒了!很高兴听到这个消息。