[英]Django REST framework foreign keys and filtering
I have following models in django app:我在 Django 应用中有以下模型:
models.py :模型.py :
class Make(BaseModel):
slug = models.CharField(max_length=32) #alfa-romeo
name = models.CharField(max_length=32) #Alfa Romeo
def __unicode__(self):
return self.name
class Model(BaseModel):
make = models.ForeignKey(Make) #Alfa Romeo
name = models.CharField(max_length=64) # line[2]
engine_capacity = models.IntegerField()
trim = models.CharField(max_length=128) # line[4]
And serializers.py :和serializers.py :
from .models import Make,Model
from rest_framework import serializers
class MakeSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = Make
fields = ('url', 'slug', 'name')
class ModelSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = Model
fields = ('url', 'make', 'name', 'trim', 'engine_capacity')
and also views.py :还有views.py :
from rest_framework import viewsets
from rest_framework import filters
from rest_framework import generics
from .models import Make, Model
from .serializers import MakeSerializer, ModelSerializer
class MakeViewSet(viewsets.ModelViewSet):
queryset = Make.objects.all()
serializer_class = MakeSerializer
filter_backends = (filters.DjangoFilterBackend,)
class ModelViewSet(viewsets.ModelViewSet):
make = MakeSerializer
queryset = Model.objects.all()
serializer_class = ModelSerializer
filter_backends = (filters.DjangoFilterBackend,)
What I need to to, I want to fetch all Models manufactured by specific make.我需要做什么,我想获取由特定品牌制造的所有模型。 How can I get all models with particular make foreign key using query params?
如何使用查询参数获取具有特定 make 外键的所有模型? And my 2nd question - can I filter results using queryparams to get models with specific engine_capacity?
我的第二个问题 - 我可以使用 queryparams 过滤结果以获得具有特定引擎容量的模型吗?
One comment: It would be perfect, if I can to query results using something like this in url: /api/models/?make=ford
where make is slug
field in Make
model一条评论:如果我可以在 url:
/api/models/?make=ford
中使用类似这样的内容查询结果,那就太完美了,其中make是Make
模型中的slug
字段
You can specify filter_fields = ('make__slug', )
in your view set.您可以在视图集中指定
filter_fields = ('make__slug', )
。 Don't forget to include filter_backends = (DjangoFilterBackend, )
as well.不要忘记包含
filter_backends = (DjangoFilterBackend, )
。 Also you will need to add django-filter
dependency.您还需要添加
django-filter
依赖项。
class ModelViewSet(viewsets.ModelViewSet):
queryset = Model.objects.all()
serializer_class = ModelSerializer
filter_backends = (filters.DjangoFilterBackend,)
filter_fields = ('make__slug',)
Then you query like /api/models/?make__slug=ford
.然后你像
/api/models/?make__slug=ford
这样的查询。 Note double underscore symbol.注意双下划线符号。
If you don't like make__slug
keyword argument in the URL, then you can create a filter class:如果你不喜欢 URL 中的
make__slug
关键字参数,那么你可以创建一个过滤器类:
import django_filters
from myapp.models import Make
class ModelFilter(django_filters.FilterSet):
make = django_filters.ModelChoiceFilter(field_name="make__slug",
queryset=Make.objects.all())
class Meta:
model = Model
fields = ('make',)
and then进而
class ModelViewSet(viewsets.ModelViewSet):
make = MakeSerializer
queryset = Model.objects.all()
serializer_class = ModelSerializer
filter_backends = (filters.DjangoFilterBackend,)
filter_class = ModelFilter
/api/models/?make=ford
should work. /api/models/?make=ford
应该可以工作。
urls.py网址.py
url('^model/by/(?P<make>\w+)/$', ModelByMakerList.as_view()),
views.py视图.py
class ModelByMakerList(generics.ListAPIView):
serializer_class = ModelSerializer
def get_queryset(self):
"""
This view should return a list of all models by
the maker passed in the URL
"""
maker = self.kwargs['make']
return Model.objects.filter(make=maker)
For more info checkout the docs .有关更多信息,请查看文档。
You can also use filtering with QUERY_PARAMS, but IMHO this looks better.您也可以使用 QUERY_PARAMS 过滤,但恕我直言,这看起来更好。
To expand on @vladimir-prudnikov's answer :要扩展@vladimir-prudnikov 的回答:
Things changed a bit in recent versions of django-filter.在 django-filter 的最新版本中,事情发生了一些变化。 You probably want:
你可能想要:
class ModelFilter(django_filters.FilterSet):
make = django_filters.ModelChoiceFilter(field_name='make__slug',
to_field_name='slug',
queryset=Make.objects.all())
class Meta:
model = Model
fields = ('make',)
See https://django-filter.readthedocs.io/en/master/ref/filters.html#field-name and https://django-filter.readthedocs.io/en/master/ref/filters.html#to-field-name请参阅https://django-filter.readthedocs.io/en/master/ref/filters.html#field-name和https://django-filter.readthedocs.io/en/master/ref/filters.html#to -字段名称
What you need to do in your view is something like this: It is called "Lookups that span relationships"在您看来,您需要做的事情是这样的:它被称为“跨越关系的查找”
queryset = Model.objects.filter(make__name__exact='Alfa Romeo')
the filtering of models with specific engine capacity is similar具有特定发动机容量的模型的过滤是相似的
queryset = Model.objects.filter(engine_capacity__exact=5)
if you want both filters combined, you can chain them:如果你想结合两个过滤器,你可以链接它们:
queryset = Model.objects.filter(make__name__exact='Alfa Romeo').filter(engine_capacity__exact=5)
more examples can be found here django query making可以在此处找到更多示例django 查询制作
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.