我正在设置一个系统,其中一个用户将图像发布到 Django 服务器,而 N 个用户将分别并行查看所发布图像的子集。我似乎无法在 Django 中找到排队机制来完成此任务。最接近的是将最新的图像与filter()一起使用,但这只会一遍又一遍地发送最新的图像,直到新的图像出现。任务队列没有帮助,因为这不是周期性任务,它仅在用户请求下一张图片时发生。我有一个用于上传图像的 View 集,另一个用于获取图像。我考虑过使用python线程安全队列。卸载器会将上传的图像 pk 入队,当多个用户请求新图像时,发送 Viewset 会将图像 pk 出队并将其发送给最近请求图像的用户,然后将下一个出队给第二个最近的用户,等等...
但是,我仍然觉得这里可能存在一些竞争条件。我读到 Django 是线程安全的,但该应用程序可能会变得非线程安全。此外,队列需要是全局的才能在 View 集之间共享,这感觉是不好的做法。有没有更好、更安全的方法来解决这个问题?
编辑
这里是关于我想要完成的任务的更多细节,并为其提供一些背景信息。发布照片的用户是连接到无人机的智能手机。它将以固定的时间间隔将天空中的图片发布到 Django 服务器。因为会有很多图片进来。我希望能够让多个用户分担查看所有图片的工作量(即没有两个用户应该看到同一张图片)。因此,当用户联系 Django 服务器时,说“将您拥有的下一张图片发送给我,或者将您拥有的下 3 张图片发送给我,等等...”。然而,多个用户可能同时这么说。因此 Django 需要对图片保持某种排序,这就是为什么我说队列并弄清楚如果同时有多个用户请求时如何将其传递给用户。因此,一个 View 集用于智能手机发布照片,另一个 View 集用于用户索要照片。我正在寻找一种线程安全的方法来做到这一点。到目前为止我唯一的想法是使用Python的线程安全队列并将其作为 View 集的全局队列。但是,我觉得这是不好的做法,并且我不确定它对于 Django 是否是线程安全的。
最佳答案
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]
关于python - 在Django中对要请求的图片进行排队,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36202899/