2015-09-17 71 views
0

我是一個很新的Django和Django的阿比REST框架Django的API休息過濾多對多

我試圖發展與一個多對多關係

models.py

class Category(models.Model): 
    name = models.CharField(max_length=100) 

class Apartment(models.Model): 
    id_2 = models.IntegerField(default= None) 
    neighborhood = models.CharField(max_length=100) 
    name = models.CharField(max_length=120) 
    district = models.CharField(max_length=120) 
    created = models.DateTimeField() 
    cats = models.ManyToManyField(Category) 
    address = models.CharField(max_length=200) 
    postal_code = models.IntegerField() 
    latitude = models.FloatField() 
    longitude = models.FloatField() 
relationated兩種型號的API

serializers.py

class CategorySerializer(serializers.HyperlinkedModelSerializer): 
    class Meta: 
     model = Category 
     fields = ('id', 'name') 

class AptSerializer(serializers.HyperlinkedModelSerializer): 

    cats = CategorySerializer(many=True, read_only=True) 

    class Meta: 
     model = Apartment 
     fields = ('id_2', 'neighborhood', 'name','district','created','cats','address','postal_code','latitude','longitude') 

view.py

class AptViewSet(viewsets.ModelViewSet): 
    """ 
    API endpoint that allows groups to be viewed or edited. 
    """ 
    queryset = Apartment.objects.all() 
    serializer_class = AptSerializer 
    filter_backends = (filters.DjangoFilterBackend,) 
    filter_fields = ('id_2', 'neighborhood', 'name', 'district','created','cats','address','postal_code','latitude','longitude') 

routers.py

router.register(r'apartments', views.AptViewSet) 

正如你可以看到它實現DjangoFilterBackend所以現在我可以篩選網址鍵入

http://localhost:8000/apartments/?district=Eixample 

和我得到這個

{ 
    "id_2": 1044121532, 
    "neighborhood": "la Nova Esquerra de l'Eixample", 
    "name": "Hotel Exe AB Viladomat", 
    "district": "Eixample", 
    "created": "2001-02-13T00:00:00Z", 
    "cats": [ 
     { 
      "id": 1073, 
      "name": "Allotjament" 
     }, 
     { 
      "id": 1075, 
      "name": "Hotels" 
     }, 
     { 
      "id": 1076, 
      "name": "3 estrelles" 
     } 
    ], 
    "address": "Viladomat 197", 
    "postal_code": 8015, 
    "latitude": 41.383665702777776, 
    "longitude": 2.151834694444444 
}, 

我想要t o讓請求像

http://localhost:8000/apartments/?cats_name=Hotels 

但它不工作,任何想法,在哪裏將從現在的道路? 編寫一個自定義過濾器? 爲Category對象編寫另一個ViewSet?

謝謝

回答

1

Manager提供的根QuerySet描述數據庫表中的所有對象。但是,通常情況下,您只需要選擇完整對象集的一部分。

但在這裏,您將可以通過查詢參數,並在整個查詢集

views.py

class AptViewSet(viewsets.ModelViewSet): 
    """ 
    API endpoint that allows groups to be viewed or edited. 
    """ 
    queryset = Apartment.objects.all() 
    serializer_class = AptSerializer 

    def get_queryset(self): 
     queryset = super(AptViewSet, self).get_queryset() 
     cats_name = self.request.query_params.get('cat_name', None) 
     if cats_name: 
      queryset = queryset.filter(cats__name=cats_name) 
     return queryset 

過濾如果你能遵循這個職位編寫自定義過濾器How to Pass kwarg to Filter

+0

謝謝@seenu s它爲我工作 唯一的問題是getqueryset中的參數必須是(self) 'class AptViewSet( viewsets.ModelViewSet): 「」「 API端點允許查看或編輯組。 」「」 queryset = Apartment.objects。所有() serializer_class = AptSerializer DEF get_queryset(個體): 查詢集=超級(AptViewSet,自我).get_queryset() cats_name = self.request.query_params.get( 'cat_name',無) 如果cats_name是不無: queryset = queryset.filter(cats__name = cats_name) return queryset' – PereCullera

+0

您能否接受答案會對其他人有幫助? –

0

退房的查詢參數過濾this鏈接。

您將覆蓋序列化程序中的get_queryset方法。

+0

謝謝您答案,但這已經實現了,因爲我使用DjangoFilterBackend所以url鍵入http:// localhost:8000/apartments /?district = Eixample工作,問題是當我試圖篩選類別ManyToMany相關字段中的url類型HTTP://本地主機: 8000/apartments /?cats_name = Hotels – PereCullera

+0

嗯,你可以在過濾列表中將'cats'改成'cats__name'嗎? – Erik

+0

我使用cats__name作爲我讀過的地方雙下劃線是獲取相關字段的方式 – PereCullera