2013-08-29 28 views
4

我是Django框架和Django REST框架的新手,但我已經完成了基本的安裝和實現運行。當我爲單個對象調用域時,它的功能就像一個魅力一樣,例如http://mydomain.com/location/1(其中1是主鍵)。這給了我喜歡的JSON響應:如何使用rest_framework和Django獲得多個對象的響應

{"id": 1, "location": "Berlin", "country": 2} 

..和http://mydomain.com/country/2樣應答:

{"id": 2, "country": "Germany"} 

我需要什麼: 現在我需要得到多個位置,例如當調用域名http://mydomain.com/all_locations/。我希望類似這樣的回覆:

[ 
    {"id": 1, "location": "Berlin", "country": 2}, 
    {"id": 2, "location": "New York", "country": 4}, 
    {"id": 3, "location": "Barcelona", "country": 5}, 
    {"id": 4, "location": "Moscow", "country": 7} 
] 

這是可選的:在第二步我很想有多個國家和地區的一個迴應時,我打電話http://mydomain.com/mix_all_locations_countries/,例如:

[ 
    {"locations": 
    {"id": 1, "location": "Berlin", "country": 2}, 
    {"id": 2, "location": "New York", "country": 4}, 
    {"id": 3, "location": "Barcelona", "country": 5}, 
    {"id": 4, "location": "Moscow", "country": 7} 
    }, 
    {"countries": 
    {"id": 1, "country": "Brazil"} 
    {"id": 2, "country": "Germany"}, 
    {"id": 3, "country": "Portugual"} 
    {"id": 4, "country": "USA"}, 
    {"id": 5, "country": "Spain"}, 
    {"id": 6, "country": "Italy"} 
    {"id": 7, "country": "Russia"} 
    } 
] 

這是我迄今爲止的實現(只顯示位置的實現):

in models.py

class Location(models.Model): 
    # variable id and pk are always available 
    location = models.CharField(max_length=100) 
    country = models.ForeignKey("Country") 

serializers.py

class LocationsSerializer(serializers.ModelSerializer): 
    country_id = serializers.Field(source='country.id') 

    class Meta: 
     model = Location 
     fields = (
      'id', 
      'location', 
      'country_id', 
     ) 

views.py

class LocationAPIView(generics.RetrieveAPIView): 
    queryset = Location.objects.all() 
    serializer_class = LocationSerializer 

urls.py

url(r'^location/(?P<pk>[0-9]+)/$', views.LocationAPIView.as_view(), name='LocationAPIView') 

我試過了:我想我不需要修改模型和序列化程序,因爲它在調用上面提到的域時用於單個對象。所以我試圖在views.py中實現LocationsViewSet,並在urls.py中添加了一個新的url,但是我失敗了。任何想法如何我可以實現它?也許只是定義LocationAPIView的方法和改變定義類似這樣的URL:

url(r'^all_locations/$', views.LocationAPIView.get_all_locations(), name='LocationAPIView') 

在此先感謝,我會感激任何幫助。

最好的問候, 邁克爾

回答

7

首先亮相,讓我們忘掉viewsets的時刻 - 他們做一些事情更加簡單,而且還引入額外的抽象層,我不認爲你應該與現在有關。

您提到的需要的第一件事就是列出與您當前詳細信息端點相同的端點。你已經有了很多,你只需要在現有的視圖旁邊引入一個額外的視圖。

views.py

class LocationListAPIView(generics.ListAPIView): 
    queryset = Location.objects.all() 
    serializer_class = LocationSerializer 

class LocationDetailAPIView(generics.RetrieveAPIView): 
    queryset = Location.objects.all() 
    serializer_class = LocationSerializer 

現在線了在URLconf兩種觀點。

urls.py

url(r'^location/$', views.LocationListAPIView.as_view(), name='location-list'), 
url(r'^location/(?P<pk>[0-9]+)/$', views.LocationDetailAPIView.as_view(), name='location-detail') 

請注意,我也改變了URL名稱樣式,使其與一般的Django的約定更標準。

接下來,您想要一個合併位置+國家/地區視圖。你將不只是能夠使用現有的通用視圖,而且因爲它是相當定製行爲,但它是很容易寫...

views.py一個觀點:

class CombinedAPIView(APIView): 
    def get(self, request): 
     locations = Location.objects.all() 
     countries = Country.objects.all() 

     location_serializer = LocationSerializer(locations, many=True) 
     country_serializer = CountrySerializer(countries, many=True) 

     return Response({ 
      'countries': country_serializer.data, 
      'locations': location_serializer.data 
     }) 

和接線圖向上。

urls.py

url(r'^combined/$', views.CombinedAPIView.as_view(), name='combined-list') 

請注意,你不需要使用串行所有生成響應時,你也可以同樣使出渾身每個實例所需的字段,用於構建數據在視圖本身中明確地顯示響應,但將模型實例映射到數據字典是一種很好的標準方法。

希望這會給你足夠的開始。 :)

+0

謝謝湯姆!我嘗試了你的方法,第二部分與CombinedAPIView工作很好!但是,第一個建議不起作用。這可能是因爲我正在使用generics.RetrieveAPIView?以下是錯誤: '預期視圖LocationListAPIView將使用名爲「pk」的URL關鍵字參數進行調用。修正你的URL conf,或正確設置視圖上的'.lookup_field'屬性。' – Michael

+0

之後,我只是試圖使用CombinedAPIView來測試URL: 'url(r'^ location/$',views.CombinedAPIView.as_view (),name ='location-list'),' 這可行,但它不是解決方案:)希望你能幫我解決這個錯誤。提前致謝。 – Michael

+0

好吧,我修正了這個使用API​​View代替。無論如何,你有一個想法如何解決它與generics.RetrieveAPIView ??這裏是爲我工作的解決方案: '類LocationListAPIView(APIView): DEF得到(個體經營,請求): 位置= Location.objects.all() location_serializer = LocationSerializer(地點,許多= TRUE) return響應({'locations':location_serializer.data, })' – Michael

相關問題