我正在建立一个系统,其中一个用户将图像发布到Django服务器,N个用户将分别并行查看已发布图像的子集。我似乎无法在Django中找到一个排队机制来完成这项任务。最接近的是使用带有filter()的最新版本,但这会一直反复发送最新图像,直到新版本出现。任务队列没有帮助,因为这不是一个周期性任务,它只发生在用户要求下一张图片时。我有一个Viewset用于上传图像,另一个用于提取。我想过使用python线程安全的Queue。卸载程序将上传的图像pk排队,当多个用户请求新图像时,发送的Viewset将使图像pk出列并将其发送给请求图像的最新用户,然后下一个用户出列到第二个最近的用户和等......
但是,我仍然觉得这里有一些竞争条件。我读到Django是线程安全的,但该应用程序可以变得非线程安全。此外,Queue需要全局化才能在Viewsets中共享,这感觉就像是不好的做法。是否有更好,更安全的方式来解决这个问题?
修改
以下是我正在努力完成的更多细节,并为其提供一些背景信息。发布图片的用户是连接到无人机的智能手机。它将以恒定的间隔将天空中的图片发布到Django服务器。由于会有很多图片进来。我希望能够让多个用户分担查看所有图片的工作量(即没有两个用户应该看到相同的图片)。因此,当用户联系Django服务器时,说“给我发送下一张图片或者给我发送你接下来的3张图片等等”。但是,多个用户可能会同时说这个。因此Django需要对图片进行某种排序,这就是为什么我说Queue并想出如何将其传递给用户,如果他们不止一次要求的话。因此,一个Viewset用于智能手机发布图片,另一个用于用户要求图片。我正在寻找一种线程安全的方法来做到这一点。到目前为止,我唯一的想法是使用Python的线程安全队列,并使其成为Viewsets的全局队列。但是,我觉得这是不好的做法,我不确定它是否与Django是线程安全的。
答案 0 :(得分:1)
Django本身没有队列,但你可以很容易地模拟它。就个人而言,我可能会使用像RabbitMQ这样的外部服务,但如果你愿意,可以在纯Django中完成。添加单独的ImageQueue模型以保存对传入图像的引用,并使用事务管理确保同时请求不返回相同的图像。也许这样的事情(当然这纯粹是概念代码的证明)。
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]