我正在构建一个与Django数据库对话的SMS API,这是一个数百人的联系信息列表。字段如下:名字,姓氏,电话号码和职位。
我在本地服务器上使用此网址时收到回复:
http://localhost:8000/sources/id
我想要做的是使用此网址向同一个数据库发出请求:
http://localhost:8000/sources/first_name-last_name
我已经调查过有关字段查找的多个问题,但没有任何帮助。这是我的serializers.py的样子:
from rest_framework import serializers, viewsets
from text_source.models import Source
class SourceSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = Source
fields = ('id','first_name','last_name','title','organization','city','cell_phone','office_phone')
lookup_field = 'first_name'
class SourceViewSet(viewsets.ModelViewSet):
queryset = Source.objects.all()
serializer_class = SourceSerializer
lookup_field = ('first_name')
我不确定使用/ first_name-last_name作为url的终点是最佳做法,但是,理论上我正在做的事情,它会起作用。
理想情况下,我希望有人在文本中输入FIRSTNAME LASTNAME并让API通过将全名连接到数据库中的ID来返回正确的信息。任何提示,以实现这一点将不胜感激。
urls.py
from django.conf.urls import include, url
from django.contrib import admin
from django.views.generic.base import TemplateView
from django.contrib.auth.models import User
from rest_framework import routers, serializers, viewsets
from app import views
from app.serializers import SourceSerializer, SourceViewSet
router = routers.DefaultRouter()
router.register(r'sources', SourceViewSet)
urlpatterns = [
url(r'^page/$', TemplateView.as_view(template_name='base.html')),
url(r'^page/', include(router.urls)),
url(r'^admin/', include(admin.site.urls)),
url(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework')),
url(r'^page/incoming/message$', views.incoming_message)
]
答案 0 :(得分:1)
我会尝试做类似下面的例子。您可以将kwargs更改为您最终使用的任何内容。
<强> 串行器: 强>
class SourceUrlField(serializers.HyperlinkedIdentityField):
def get_url(self, obj, view_name, request, format):
kwargs = {
'first_name': obj.first_name,
'last_name': obj.last_name
}
return reverse(view_name, kwargs=kwargs,
request=request, format=format)
class SourceSerializer(serializers.HyperlinkedModelSerializer):
url = SourceUrlField("view_name")
class Meta:
model = Source
fields = (
'id',
'url',
'first_name',
'last_name',
'title',
'organization',
'city',
'cell_phone',
'office_phone',
)
根据Joey的推理,如果可能,我会尽量避免使用first_name
和last_name
。但是,我刚刚向您展示的示例将适用于您选择使用的任何一个kwargs。
答案 1 :(得分:0)
我认为您可能会遇到/sources/first_name-last_name
作为端点的问题,因为您永远无法保证名称的唯一性,而且名称也可能包含破折号。我建议将/sources/id
(大概是/sources/
)作为您的终点,并且只允许过滤。
您可以阅读in the DRF documentation了解有关过滤的更多详细信息,但基本示例(安装django-filter之后)将如下所示:
from rest_framework import filters, serializers, viewsets
from text_source.models import Source
class SourceSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = Source
fields = ('id','first_name','last_name','title','organization','city','cell_phone','office_phone')
class SourceViewSet(viewsets.ModelViewSet):
queryset = Source.objects.all()
serializer_class = SourceSerializer
filter_backends = (filters.DjangoFilterBackend,)
filter_fields = ('first_name', 'last_name')
完成此操作后,您可以按/sources/?first_name=Bob&last_name=Dobbs
行构建网址以执行搜索并返回ID。
另请注意,您的示例中有一个非常重要的错误。您将ViewSet上的lookup_field指定为('first_name')
。这个确切的语法,因为元组中只有一个元素,通过将字符串'first_name'
视为可迭代来产生非常多的不良副作用,创建一个类似('f', 'i', 'r', 's', 't', '_', 'n', 'a', 'm', 'e')
的元组。为了防止这种情况,您希望使用的是('first_name', )
。请注意尾随的逗号。
答案 2 :(得分:0)
您可以在运行时覆盖lookup_field
,具体取决于您在GET参数中获得的属性。只要您只想定义一个视图和网址,就不能使用kwargs。
示例网址: -
/sources/?parameter=first_name&first_name='someone'
相应地更改您的视图集: -
class SourceViewSet(viewsets.ModelViewSet):
queryset = Source.objects.all()
serializer_class = SourceSerializer
lookup_field = ('first_name')
def initial(self, request, *args, **kwargs):
parameter = request.data.get('parameter')
self.lookup_field = parameter
kwargs[parameter] = request.data.get(parameter)
super(SourceViewSet, self).initial(request, *args, **kwargs)