Dra*_*Dev 2 python django django-rest-framework
这是我的views.py:
class LanguageViewSet(viewsets.ModelViewSet):
queryset = Language.objects.all().order_by('name')
serializer_class = LanguageSerializer
class FrameworkViewSet(viewsets.ModelViewSet):
queryset = Framework.objects.all()
serializer_class = FrameworkSerializer
class SelectedLanguageViewSet(viewsets.ModelViewSet):
queryset = Language.objects.all()
serializer_class = FrameworkSerializer
def get_queryset(self):
request = self.request
language_id = request.query_params.get('language_id')
language = Language.objects.filter(id=language_id)
self.queryset = language.framework_set.all()
return self.queryset
Run Code Online (Sandbox Code Playgroud)
还有我的urls.py:
router = routers.DefaultRouter()
router.register(r'languages', views.LanguageViewSet)
router.register(r'frameworks', views.FrameworkViewSet)
router.register(r'language/<int:language_id>', views.SelectedLanguageViewSet)
urlpatterns = [
path('', include(router.urls)),
path('api-auth/', include('rest_framework.urls', namespace='rest_framework'))
]
Run Code Online (Sandbox Code Playgroud)
然而,只有languages和frameworks工作。language不存在。这是因为get_queryset? 我什至尝试删除<int:language_id>url 参数中的 ,但它仍然不会显示。
编辑:请
原谅我的天真,我对 django 和 DRF 还是很陌生
我的意思是这样的(没有 DRF):
在views.py 中:
def frameworks_from_language(request, language_id):
language = Language.objects.get(pk=language_id)
if language == None:
# Do some stuffs
frameworks = language.framework_set.all()
template = 'app/language.html'
context = {
'frameworks': frameworks
}
return render(request, template, context)
Run Code Online (Sandbox Code Playgroud)
在urls.py 中:
path('language/<int:language_id>', views.frameworks_from_language, name='getframeworks')
Run Code Online (Sandbox Code Playgroud)
所以整个流程是:
这是在一个普通的基于模板的 Django 上工作的。但是我不知道如何在 DRF 上使用所有视图集等执行这样的操作。
是的,这是因为您的get_queryset(和您的 URL 定义)。
首先,<int:language_id>从 URL 前缀中删除,因为 DRF 路由器会自动为您生成列表和详细 URL 端点。此外,当您使用正则表达式时,路径language/<int:language_id>是按字面意思理解的(在使用时<int:language_id>有含义,而path不是re_path)。
在您的 中SelectedLanguageViewSet.get_queryset,您试图返回Framework与某个相关的所有实例Language(您认为您会从language_id查询参数中获取该实例)。viewset 是用于Language模型的,最多你应该对queryset里面的默认值做一些过滤get_queryset;绝对不要从另一个模型返回完全不同的查询集。当你通过时会发生什么(在修复你的 URL 之后)/language/1/?(1 是LanguageID 还是FrameworkID?提示:根据您当前的设计,它会引用Framework实例 ID)。
FWIW,URL 捕获作为kwargs视图集实例(即self.kwargs)中的属性,而不是通过查询字符串。
回复编辑:
要在 DRF 中实现它,您可以为仅包含frameworks字段的语言定义序列化程序:
from viewsets import ReadOnlyModelViewSet
class SelectedLanguageViewSet(ReadOnlyModelViewSet):
queryset = Language.objects.all()
serializer_class = LangaugeRelationSerializer
Run Code Online (Sandbox Code Playgroud)
仅应支持list和retrieve操作,因此继承自ReadOnlyModelViewSet.
现在,序列化程序(只有一个字段 -- frameworks):
class LangaugeRelationSerializer(serializers.ModelSerializer):
frameworks = FrameworkSerializer(source='framework_set', many=True)
class Meta:
model = Language
fields = ('frameworks',)
Run Code Online (Sandbox Code Playgroud)
默认情况下,ModelSerializer将相关字段设置为PrimaryKeyRelatedField,因此相关对象表示为其主键。如果你想要而不是使用FrameworkSerializer:
class LangaugeRelationSerializer(serializers.ModelSerializer):
frameworks = serializers.PrimaryKeyRelatedField(source='framework_set', many=True)
class Meta:
model = Language
fields = ('frameworks',)
Run Code Online (Sandbox Code Playgroud)
作为PrimaryKeyRelatedField默认设置,您还可以定义sourcein Meta.extra_kwargs(以免您自己编写字段定义):
class LangaugeRelationSerializer(serializers.ModelSerializer):
class Meta:
model = Language
fields = ('frameworks',)
extra_kwargs = {
'frameworks': {
'source': 'framework_set',
'many': True,
},
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
152 次 |
| 最近记录: |