在我的数据库中,我有两个表-users
和user_properties
我需要使用GET参数phone
过滤输出。但是,这两个表都具有列phone
并具有不同的值。
当我执行GET请求时(例如“?phone = 123456789”),我不仅需要使用user_properties.phone,而且还要使用user.phone通过电话号码搜索用户!
我用Google搜索并找到了一种使用get_queryset(filtering)和SerializerMethodField(修改输出)来部分实现此目的的方法:
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'
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
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
列过滤结果?或在两个表格中搜索并获得拥有此电话号码之一的用户?有可能吗还是我的方法不正确?
谢谢!
答案 0 :(得分:1)
这个问题更多的是关于Django ORM而不是Django REST框架,但是像这样重写get_queryset
方法将在两个模型的phone
字段中进行搜索:
from django.db.models import Q
...
def get_queryset(self):
queryset = self.queryset
# phone number from GET
phone = self.request.query_params.get('phone')
if phone:
queryset = queryset.filter(
Q(phone__contains=phone)
| Q(user__phone__contains=phone)
)
return queryset