在Django rest框架中过滤给定距离内的用户

Posted

技术标签:

【中文标题】在Django rest框架中过滤给定距离内的用户【英文标题】:filter users within a given distance in Django rest framework 【发布时间】:2021-12-07 04:49:42 【问题描述】:

我正在尝试在 Django rest 框架中实现一个自定义过滤器,它返回给定距离内的用户,我正在使用 Django 过滤器。我假设前端已经提供了纬度和经度。

这是我试过的。我不知道这是否是正确的做法。 我遇到以下错误

'RenameAttributes' object is not iterable

这是我的代码

Views.py

def calculateDistance(lon1, lat1, lon2, lat2):
    lon1, lat1, lon2, lat2 = map(radians, [lon1, lat1, lon2, lat2])
    return 6371 * (
        acos(sin(lat1) * sin(lat2) + cos(lat1) * cos(lat2) * cos(lon1 - lon2))
    )
class CustomFilter(django_filters.rest_framework.DjangoFilterBackend):
    def filter_queryset(self, request , queryset,view):
        alluser = queryset
        newQueryset = []
        distparam = request.GET.get('distance')
        if distparam and bool(int(distparam)):
            for user in alluser:
                current_user_long = request.user.Longitude
                current_user_lat = request.user.Latitude
                alluser_long = user.Longitude
                alluser_lat = user.Latitude
                distance = calculateDistance(current_user_long, current_user_lat, alluser_long, alluser_lat)
                if distance > distparam:
                    newQueryset.push(user)
            return newQueryset
        return queryset
class UserFilter(filters.FilterSet):
    class Meta:
        model = User
        fields =['gender', 'last_name', 'first_name' ]
class UserListView(generics.ListAPIView):

    queryset = User.objects.all()
    serializer_class = UserSerializer
    filterset_class = UserFilter
    filter_backends = CustomFilter

模型.py

class User(AbstractUser):
   username = None
   email = models.EmailField(
       max_length=100, verbose_name='email', unique=True)
   gender = models.CharField(
       max_length = 20,
       choices = GENDER_CHOICES,
       default = 'М'
       )  
   avatar= ProcessedImageField(upload_to='avatars',
                                          processors=[ResizeToFill(400, 400), Watermark()],
                                          format='JPEG',
                                          options='quality': 72)    
   likes = models.ManyToManyField('User', blank=True, related_name="like")
   latitude = models.DecimalField(max_digits=22, decimal_places=16, blank=True, null=True)
   longitude = models.DecimalField(max_digits=22, decimal_places=16, blank=True, null=True)
   USERNAME_FIELD = 'email'
   REQUIRED_FIELDS = []
   objects = UserManager()

【问题讨论】:

考虑使用GeoDjango你可以用它来做距离查询docs.djangoproject.com/en/3.2/ref/contrib/gis/db-api/… 如果我已经实现了计算距离的函数,为什么还要使用这个库? 因为您必须针对数据库中的每个用户获取、循环并运行您的函数,这将非常低效。对数据库进行过滤会更快、更高效,因为您不必从整个用户表中传输数据 【参考方案1】:

我认为这里出现的错误与距离计算/过滤无关,可能是设置不正确 请确保 DEFAULT_FILTER_BACKENDS 是有效的元组或列表

【讨论】:

设置一切正常 你能发布你的 REST_FRAMEWORK 设置密钥 REST_FRAMEWORK = 'DEFAULT_FILTER_BACKENDS':['django_filters.rest_framework.DjangoFilterBackend'],'DEFAULT_AUTHENTICATION_CLASSES':['rest_framework_simplejwt.authentication.JWTAuthentication',],

以上是关于在Django rest框架中过滤给定距离内的用户的主要内容,如果未能解决你的问题,请参考以下文章

如何在 django rest 框架中的 postgres JSONField 上应用过滤器?

Django rest框架按日期时间过滤

Django REST框架外键和过滤

django rest框架过滤器

如何将过滤器应用于 Django REST 框架中的嵌套资源?

如何使用 django rest 框架从 GET 请求的查询参数中过滤多个 id?