【发布时间】:2018-11-21 13:49:06
【问题描述】:
在我的数据库中,我有两个表 - users 和 user_properties
我需要使用 GET 参数phone 过滤输出。但是这两个表都有 phone 列并且具有不同的值。
当我执行 GET 请求(例如“?phone=123456789”)时,我不仅需要使用 user_properties.phone,还需要使用 user.phone,通过电话号码搜索用户!
我在谷歌上搜索并找到了一种使用 get_queryset(filtering) 和 SerializerMethodField(修改输出)的方法:
models.py
class User(models.Model):
balance = models.DecimalField(decimal_places=35, max_digits=40)
fio = models.CharField(max_length=64)
phone = models.CharField(max_length=64, blank=True, null=True)
class Meta:
managed = False
db_table = 'user'
class UserProperties(models.Model):
user_id = models.IntegerField(primary_key=True)
phone = models.CharField(max_length=11)
class Meta:
managed = False
db_table = 'user_properties'
views.py
class UserPropertiesViewSet(viewsets.ModelViewSet):
queryset = UserProperties.objects.all()
serializer_class = serializers.UserPropertiesSerializer
def get_queryset(self):
queryset = self.queryset
# phone number from GET
phone = self.request.query_params.get('phone')
# Search users matches in user_properties using by phone number
if phone:
queryset = UserProperties.objects.all()
users = queryset.filter(phone__contains=phone)
return users
else:
return queryset
serializers.py
class UserPropertiesSerializer(serializers.ModelSerializer):
all_phones = serializers.SerializerMethodField()
class Meta:
model = models.UserProperties
fields = ['user_id', 'phone', 'fio', 'url', 'all_phones',]
# phone numbers from user and user_properties tables
def get_all_phones(self, obj):
# search phones in <user> table by user_id
user_phones = models.User.objects.filter(id__exact=obj.user_id).values_list('phone', flat=True)
# add phones from user_properties table
result = [obj.phone,]
# add phones from user table
for phone in user_phones[0].split(','):
result.append(''.join(filter(lambda x: x.isdigit(), phone)))
# return list with all phones
return set(result)
我在过滤结果中得到all_phones 列:
{
"count": 1,
"next": null,
"previous": null,
"results": [
{
"user_id": 17897,
"phone": "123456789", <--- user_properties table
"fio": "....",
"url": "....",
"all_phones": [
"123456789",
"5512222",
"49543"
] <--- user_properties.phone + user.phone
}
]
}
但在get_queryset 中,我仅使用 user_properties 表中的“真实”phone 列进行过滤。如何使用“虚拟”all_phones 列过滤结果?或者在两个表中搜索并获取拥有此电话号码之一的用户?有可能吗?还是我的方法不对?
谢谢!
【问题讨论】:
-
您不能依赖 Django ORM 来搜索 2 个不同的表。您要么必须查询两次并加入结果,要么标准化您的数据并将所有电话号码移动到一个表中。
标签: django rest api django-rest-framework