Python 将在Django中请求的图片排队

Python 将在Django中请求的图片排队,python,django,multithreading,django-rest-framework,django-1.9,Python,Django,Multithreading,Django Rest Framework,Django 1.9,我正在设置一个系统,其中一个用户将向Django服务器发布图像,N个用户将分别并行查看已发布图像的子集。在Django中,我似乎找不到一种排队机制来完成这项任务。最接近的方法是使用latest with filter(),但这只会一次又一次地发送最新图像,直到新图像出现。任务队列没有帮助,因为这不是一个周期性任务,它只在用户请求下一张图片时发生。我有一个用于上传图像的视图集,另一个用于抓取。我考虑过使用python线程安全队列。卸载程序将上传的图像pk排队,当多个用户请求新图像时,发送视图集将图

我正在设置一个系统,其中一个用户将向Django服务器发布图像,N个用户将分别并行查看已发布图像的子集。在Django中,我似乎找不到一种排队机制来完成这项任务。最接近的方法是使用latest with filter(),但这只会一次又一次地发送最新图像,直到新图像出现。任务队列没有帮助,因为这不是一个周期性任务,它只在用户请求下一张图片时发生。我有一个用于上传图像的视图集,另一个用于抓取。我考虑过使用python线程安全队列。卸载程序将上传的图像pk排队,当多个用户请求新图像时,发送视图集将图像pk排队,并将其发送给最近请求图像的用户,然后下一个用户将排队给第二个最近的用户,依此类推

然而,我仍然觉得这里有一些可能的比赛条件。我读到Django是线程安全的,但是这个应用程序可以变成非线程安全的。此外,队列需要是全局的,以便在视图集之间共享,这感觉像是一种糟糕的做法。有没有更好更安全的方法

编辑


下面是我试图完成的更多细节,并给出一些背景。发布图片的用户是一部连接在无人机上的智能手机。它将以固定的间隔向Django服务器发送来自天空的图片。因为会有很多照片进来。我希望能够让多个用户分担查看所有图片的工作量(即,没有两个用户会看到相同的图片)。因此,当用户联系Django服务器时,会说“将你的下一张图片发送给我,或将你的下三张图片发送给我,等等…”。但是,多个用户可能会同时这么说。所以Django需要对图片保持某种排序,这就是为什么我说排队,并找出如何在一次有多个用户询问时将其传递给用户。因此,一个视图集用于智能手机发布图片,另一个用于用户请求图片。我正在寻找一个线程安全的方法来做到这一点。到目前为止,我唯一的想法是使用Python的线程安全队列,并将其作为视图集的全局队列。但是,我觉得这是一种糟糕的做法,我不确定Django是否是线程安全的。

Django本身没有队列,但您可以轻松地模拟它。就我个人而言,我可能会使用一个外部服务,比如rabbitMQ,但如果您愿意,可以使用纯Django。添加一个单独的ImageQueue模型来保存对传入映像的引用,并使用事务管理来确保同时请求不会返回相同的映像。可能是这样的(当然,这纯粹是概念验证代码)

类ImageQueue(models.Model): 图像=模型。OneTONE(图像) added=models.DateTimeField(auto\u now\u add=True) processed=models.DateTimeField(null=True,默认值=None) processed_by=models.ForeignKey(用户,null=True,默认值=None) 类元: order_by=(“已添加”) ... #在无人机使用的传入图像API中 def post_图像(请求): image=image() ... 无论你做什么来发布图片。。。 image.save() queue=ImageQueue.objects.create(image=image) ... 不管你还需要做什么。。。 #在API中,用户将使用 从django.db导入事务 @原子事务 def请求_图像(请求): user=request.user num=request.POST['num']#请求的图像数 queue\u slice=ImageQueue.objects.filter(已处理的\u isnull=True)[:num] 对于队列_切片中的q: q、 processed=datetime.datetime.now() q、 由用户处理 q、 保存() 返回[q.队列中q的图像\u切片]
我认为您需要进一步描述您正在尝试做什么以及为什么(预期行为)。如果我没有看错的话,你需要设置一个“从‘我’上次请求后获取新图像”的请求,这是每个用户的请求。e、 g.用户在上次发送请求时发送一个datime,服务器将发回自该datime之后添加的所有图像。@warath coder感谢您提到这一点。我添加了更多细节,以便您可以修改我的建议,当您添加图片时,还可以在“已查看”表中添加条目。然后,用户可以请求X张“未查看”图片。您可以锁定已查看的表格,标记已查看的X张图片,解锁表格,然后发送图片。我非常怀疑是否有“开箱即用”的解决方案。您的处理程序应该只是盲目地保存图片,同时在RabbitMQ队列中发布消息,以防止多个使用者在用户“咨询”另一个处理程序查看图片时看到同一个图像。 class ImageQueue(models.Model): image = models.OneToOne(Image) added = models.DateTimeField(auto_now_add=True) processed = models.DateTimeField(null=True, default=None) processed_by = models.ForeignKey(User, null=True, default=None) class Meta: order_by=('added') ... # in the incoming image API that drone uses def post_an_image(request): image = Image() ... whatever you do to post an image ... image.save() queue = ImageQueue.objects.create(image=image) ... whatever else you need to do ... # in the API your users will use from django.db import transaction @transaction.atomic def request_images(request): user = request.user num = request.POST['num'] # number of images requested queue_slice = ImageQueue.objects.filter(processed__isnull=True)[:num] for q in queue_slice: q.processed = datetime.datetime.now() q.processed_by = user q.save() return [q.image for q in queue_slice]