在 Django REST Framework 中使用 url 传递查询
Pass query with url in Django REST Framework
我觉得这应该很简单,但我所做的并没有得到回报。
在 Django 中,我的应用程序中有这个 urls.py:
from django.urls import path
from .views import PostcodessAPIListView, PostcodesAPIID, PostcodesWithinRadius
urlpatterns = [
path("<str:postcode>/<int:radius_km>", PostcodesWithinRadius.as_view(), name="results_api_radius"),
path("", PostcodessAPIListView.as_view(), name="results_api_list"),
path("<int:pk>", PostcodesAPIID.as_view(), name="results_api_detail"),
]
我有这样的观点,应该采用邮政编码和以公里为单位的半径,调用外部 api 将邮政编码转换为经度和纬度,然后再次调用外部 api 以获取特定半径内的邮政编码。
class PostcodesWithinRadius(generics.RetrieveAPIView):
serializer_class = PostcodeSerializer
def get_queryset(self):
postcode = self.request.query_params.get('postcode', None)
radius_km = self.request.query_params.get('radius_km', None)
print(postcode, radius_km)
postcodes = self.get_postcodes_within_radius(postcode, radius_km)
print(postcodes)
return Postcode.objects.filter(postcode__in=postcodes)
def get_postcodes_within_radius(self, postcode, radius_km):
radius_km = 3
postcodes_within_radius = []
if radius_km <= 20:
radius = radius_km * 1000
else:
raise ValueError('Radius cannot be over 20km.')
GET_LAT_LON_URL = f"{POSTCODE_URL}?"
postcode_query = {
"query": postcode
}
postcode_data = requests.get(GET_LAT_LON_URL, headers=None, params=postcode_query).json()
print(postcode_data)
querystring = {
"longitude": postcode_data['result'][0]['longitude'],
"latitude": postcode_data['result'][0]['latitude'],
"wideSearch": radius,
"limit": 100,
}
res = requests.get(POSTCODE_URL, headers=None, params=querystring).json()
for postcode in res['result']:
postcodes_within_radius.append(postcode['postcode'])
return postcodes_within_radius
但是,邮政编码和半径没有通过 url 参数传递 - 给出了什么?
为什么不使用
的 get()
方法
class PostcodesWithinRadius(generics.RetrieveAPIView):
serializer_class = PostcodeSerializer
def get(self, request, **kwargs):
postcode = kwargs.get('postcode')
radius_km = kwargs.get('radius_km')
# rest of the logic
您没有将 postcode
和 radius
作为 query
参数传递,而是作为 url
参数传递。
如果您的 url
类似于:
,您的方法就可以使用
http://localhost:8000/postcodes/?postcode=0000&radius=5
但由于您使用的是 url
参数:
http://localhost:8000/<postcode>/<radius>
您需要更改 get_queryset
方法。试试这个:
def get_queryset(self):
postcode = self.kwargs.get('postcode', None)
radius_km = self.kwargs.get('radius_km', None)
print(postcode, radius_km)
postcodes = self.get_postcodes_within_radius(postcode, radius_km)
print(postcodes)
return Postcode.objects.filter(postcode__in=postcodes)
我觉得这应该很简单,但我所做的并没有得到回报。
在 Django 中,我的应用程序中有这个 urls.py:
from django.urls import path
from .views import PostcodessAPIListView, PostcodesAPIID, PostcodesWithinRadius
urlpatterns = [
path("<str:postcode>/<int:radius_km>", PostcodesWithinRadius.as_view(), name="results_api_radius"),
path("", PostcodessAPIListView.as_view(), name="results_api_list"),
path("<int:pk>", PostcodesAPIID.as_view(), name="results_api_detail"),
]
我有这样的观点,应该采用邮政编码和以公里为单位的半径,调用外部 api 将邮政编码转换为经度和纬度,然后再次调用外部 api 以获取特定半径内的邮政编码。
class PostcodesWithinRadius(generics.RetrieveAPIView):
serializer_class = PostcodeSerializer
def get_queryset(self):
postcode = self.request.query_params.get('postcode', None)
radius_km = self.request.query_params.get('radius_km', None)
print(postcode, radius_km)
postcodes = self.get_postcodes_within_radius(postcode, radius_km)
print(postcodes)
return Postcode.objects.filter(postcode__in=postcodes)
def get_postcodes_within_radius(self, postcode, radius_km):
radius_km = 3
postcodes_within_radius = []
if radius_km <= 20:
radius = radius_km * 1000
else:
raise ValueError('Radius cannot be over 20km.')
GET_LAT_LON_URL = f"{POSTCODE_URL}?"
postcode_query = {
"query": postcode
}
postcode_data = requests.get(GET_LAT_LON_URL, headers=None, params=postcode_query).json()
print(postcode_data)
querystring = {
"longitude": postcode_data['result'][0]['longitude'],
"latitude": postcode_data['result'][0]['latitude'],
"wideSearch": radius,
"limit": 100,
}
res = requests.get(POSTCODE_URL, headers=None, params=querystring).json()
for postcode in res['result']:
postcodes_within_radius.append(postcode['postcode'])
return postcodes_within_radius
但是,邮政编码和半径没有通过 url 参数传递 - 给出了什么?
为什么不使用
的get()
方法
class PostcodesWithinRadius(generics.RetrieveAPIView):
serializer_class = PostcodeSerializer
def get(self, request, **kwargs):
postcode = kwargs.get('postcode')
radius_km = kwargs.get('radius_km')
# rest of the logic
您没有将 postcode
和 radius
作为 query
参数传递,而是作为 url
参数传递。
如果您的 url
类似于:
http://localhost:8000/postcodes/?postcode=0000&radius=5
但由于您使用的是 url
参数:
http://localhost:8000/<postcode>/<radius>
您需要更改 get_queryset
方法。试试这个:
def get_queryset(self):
postcode = self.kwargs.get('postcode', None)
radius_km = self.kwargs.get('radius_km', None)
print(postcode, radius_km)
postcodes = self.get_postcodes_within_radius(postcode, radius_km)
print(postcodes)
return Postcode.objects.filter(postcode__in=postcodes)