2013-02-02 36 views
1

這是我的模型如何使用反向關係在Django tastypie

class Nisit(models.Model): 

class Page(models.Model): 
followingNisit = models.ManyToManyField(Nisit,blank=True) 

這是我的資源

class NisitResource(ModelResource): 
    page = fields.ToManyField('chula.api.PageResource','page_set',null=True) 
class Meta: 
    queryset = Nisit.objects.all()  
    resource_name = 'nisit' 
    filtering = { 
     'page' : ALL_WITH_RELATIONS, 
     'id' : ALL, 
    } 

class PageResource(ModelResource): 
    followingNisit = fields.ToManyField(NisitResource, 'followingNisit',null=True) 
    reporter = fields.ManyToManyField(ReporterResource,'reporter') 
    followers_count = fields.CharField(attribute='followers_count') 

class Meta: 
    queryset = Page.objects.all() 
    resource_name = 'page' 
    authorization= Authorization() 
    filtering = { 
     'id':ALL, 
     'followingNisit': ALL_WITH_RELATIONS, 
    } 

當我要求這沒關係--- ---- 127.0.0.1:8000/api/v2/page/?format=json & followingNisit__id = 1

但在相反的方式,當我請求--------- 127.0.0.1:8000/api/v2/nisit/?format=json & page__id = 1,I將收到此錯誤

{"error_message": "Cannot resolve keyword 'page_set' into field. Choices are: displayName, facebook, faculty, friend, id, major, n_id, name, page, password, picture, reporter, year_in_school", "traceback": "Traceback (most recent call last):\n\n File \"D:\\Study\\SeniorProject\\Code\\mysite\\tastypie\\resources.py\", line 202, in wrapper\n response = callback(request, *args, **kwargs)\n\n File \"D:\\Study\\SeniorProject\\Code\\mysite\\tastypie\\resources.py\", line 441, in dispatch_list\n return self.dispatch('list', request, **kwargs)\n\n File \"D:\\Study\\SeniorProject\\Code\\mysite\\tastypie\\resources.py\", line 474, in dispatch\n response = method(request, **kwargs)\n\n File \"D:\\Study\\SeniorProject\\Code\\mysite\\tastypie\\resources.py\", line 1127, in get_list\n objects = self.obj_get_list(request=request, **self.remove_api_resource_names(kwargs))\n\n File \"D:\\Study\\SeniorProject\\Code\\mysite\\tastypie\\resources.py\", line 1890, in obj_get_list\n base_object_list = self.apply_filters(request, applicable_filters)\n\n File \"D:\\Study\\SeniorProject\\Code\\mysite\\tastypie\\resources.py\", line 1862, in apply_filters\n return self.get_object_list(request).filter(**applicable_filters)\n\n File \"C:\\Python27\\lib\\site-packages\\django\\db\\models\\query.py\", line 624, in filter\n return self._filter_or_exclude(False, *args, **kwargs)\n\n File \"C:\\Python27\\lib\\site-packages\\django\\db\\models\\query.py\", line 642, in _filter_or_exclude\n clone.query.add_q(Q(*args, **kwargs))\n\n File \"C:\\Python27\\lib\\site-packages\\django\\db\\models\\sql\\query.py\", line 1250, in add_q\n can_reuse=used_aliases, force_having=force_having)\n\n File \"C:\\Python27\\lib\\site-packages\\django\\db\\models\\sql\\query.py\", line 1122, in add_filter\n process_extras=process_extras)\n\n File \"C:\\Python27\\lib\\site-packages\\django\\db\\models\\sql\\query.py\", line 1316, in setup_joins\n \"Choices are: %s\" % (name, \", \".join(names)))\n\nFieldError: Cannot resolve keyword 'page_set' into field. Choices are: displayName, facebook, faculty, friend, id, major, n_id, name, page, password, picture, reporter, year_in_school\n"} 
+0

請幫我看TT –

+0

任何人都可以解釋這種情況嗎? –

回答

-1

這是事情,如果django tastypie作品非常相似,Django的(因爲任何人都可以想到)你用的是不好的關鍵字,在你的情況下,它不會是page_set,僅使用page代替,它會工作。

我向你推薦使用多字段名

pages = fields.ToManyField('chula.api.PageResource','page_set',null=True) 

所以正向關係是pages與落後關係page_set我現在不記得它。但無論如何它看起來會更好。

+0

我改變「page = fields.ToManyField('chula.api.PageResource','page_set',null = True)」to「pages = fields.ToManyField('chula.api。PageResource','page_set',null = True)「 正如你告訴我的,但它仍然有相同的錯誤。當我請求」http://127.0.0.1:8000/api/v2/nisit/?format=json&pages__id= 1「 –

+0

可能是NisitResource,」頁面「中的過濾元選項:ALL_WITH_RELATIONS,到」頁面「:ALL_WITH_RELATIONS,並確保元類正確縮進 –

+0

」因此,正向關係是頁面和後向關係是page_set「你能否詳細說明這一說法,我不明白。非常感謝Oscar David Arbelaez所有的答案 –

1

我也一直在努力從setup_joins拋出相同的FieldError,我想我剛剛解決了我的問題。我試圖通過多對多關係進行篩選,並且無法使fields.ToManyField()中的「_set」正常工作。在錯誤情況下並在一個簡單的過濾器中調試TastyPie代碼後,我意識到可能完全繞過對中間資源的需求。

這是什麼爲我工作,我希望它可以幫助您的情況。由於我不知道你的模型設置,我會做一個類似的例子。

一,型號:

### models.py ### 
from django.db import models 

class Ingredient(models.Model): 
    name = models.CharField(max_length=100) 
    description = models.TextField() 

    def __unicode__(self): 
     return '%s' % (self.name) 

class RecipeIngredient(models.Model): 
    recipe = models.ForeignKey('Recipe') 
    ingredient = models.ForeignKey('Ingredient') 
    weight = models.IntegerField(null = True, blank = True) 

    def __unicode__(self): 
     return '%s: %s' % (self.recipe, self.ingredient) 

class Recipe(models.Model): 
    title = models.CharField(max_length=100) 
    ingredients = models.ManyToManyField(Ingredient, through='RecipeIngredient') 

    def __unicode__(self): 
     return '%s' % (self.title) 

這裏是ModelResources的:

### api.py ### 
from tastypie.resources import ModelResource, ALL, ALL_WITH_RELATIONS 
from tastypie import fields 
from some_app.models import Ingredient, Recipe 

class IngredientResource(ModelResource): 

    class Meta: 
     queryset = Ingredient.objects.all() 
     resource_name = 'ingredient' 
     filtering = { 
      'name': ALL, 
     } 

class RecipeResource(ModelResource): 
    ingredients = fields.ToManyField(
     'some_app.api.IngredientResource', 
     'ingredients', 
     full=True) 

    class Meta: 
     queryset = Recipe.objects.all() 
     resource_name = 'recipe' 
     filtering = { 
      'title': ALL, 
      'ingredients': ALL_WITH_RELATIONS, 
     } 

注意我沒有RecipeIngredientResource,我直接掛鉤的IngredientResource,這工作,因爲配方模型包括ManyToManyField ingredients及選項through='RecipeIngredient'

一個示例URL,用於過濾參數的所有配方然後滿足特殊成分的樣子:

http://localhost:8000/api/recipes/recipe/?ingredients__name=blueberry

而且,爲了完整性,這裏的名爲「some_app」拯救任何人想要實現這個例子中輸入數據時的Django應用程序的固定:

[ 
    { 
     "pk": 1, 
     "model": "some_app.ingredient", 
     "fields": { 
      "name": "apple", 
      "description": "a tempting fruit" 
     } 
    }, 
    { 
     "pk": 2, 
     "model": "some_app.ingredient", 
     "fields": { 
      "name": "cherry", 
      "description": "a red fruit" 
     } 
    }, 
    { 
     "pk": 3, 
     "model": "some_app.ingredient", 
     "fields": { 
      "name": "blueberry", 
      "description": "a blue fruit" 
     } 
    }, 
    { 
     "pk": 4, 
     "model": "some_app.ingredient", 
     "fields": { 
      "name": "flour", 
      "description": "used for baking and stuff" 
     } 
    }, 
    { 
     "pk": 5, 
     "model": "some_app.ingredient", 
     "fields": { 
      "name": "sugar", 
      "description": "makes stuff sweet" 
     } 
    }, 
    { 
     "pk": 1, 
     "model": "some_app.recipeingredient", 
     "fields": { 
      "recipe": 1, 
      "weight": 3, 
      "ingredient": 1 
     } 
    }, 
    { 
     "pk": 2, 
     "model": "some_app.recipeingredient", 
     "fields": { 
      "recipe": 1, 
      "weight": 2, 
      "ingredient": 4 
     } 
    }, 
    { 
     "pk": 3, 
     "model": "some_app.recipeingredient", 
     "fields": { 
      "recipe": 1, 
      "weight": 4, 
      "ingredient": 5 
     } 
    }, 
    { 
     "pk": 4, 
     "model": "some_app.recipeingredient", 
     "fields": { 
      "recipe": 2, 
      "weight": 8, 
      "ingredient": 2 
     } 
    }, 
    { 
     "pk": 5, 
     "model": "some_app.recipeingredient", 
     "fields": { 
      "recipe": 2, 
      "weight": 4, 
      "ingredient": 4 
     } 
    }, 
    { 
     "pk": 6, 
     "model": "some_app.recipeingredient", 
     "fields": { 
      "recipe": 2, 
      "weight": 6, 
      "ingredient": 5 
     } 
    }, 
    { 
     "pk": 7, 
     "model": "some_app.recipeingredient", 
     "fields": { 
      "recipe": 3, 
      "weight": 15, 
      "ingredient": 3 
     } 
    }, 
    { 
     "pk": 8, 
     "model": "some_app.recipeingredient", 
     "fields": { 
      "recipe": 3, 
      "weight": 5, 
      "ingredient": 4 
     } 
    }, 
    { 
     "pk": 9, 
     "model": "some_app.recipeingredient", 
     "fields": { 
      "recipe": 3, 
      "weight": 6, 
      "ingredient": 5 
     } 
    }, 
    { 
     "pk": 1, 
     "model": "some_app.recipe", 
     "fields": { 
      "title": "Apple Pie" 
     } 
    }, 
    { 
     "pk": 2, 
     "model": "some_app.recipe", 
     "fields": { 
      "title": "Cherry Pie" 
     } 
    }, 
    { 
     "pk": 3, 
     "model": "some_app.recipe", 
     "fields": { 
      "title": "Blueberry Pie" 
     } 
    } 
] 
+0

我有一個幾乎相同的模型(沒有m2m通過模型)我遇到了完整性約束的麻煩也是如此。使用你的例子,你是否能夠發佈(並且更重要的是修補)具有相同成分的不同收據而不會違反約束條件? – haki

+0

@haki我遇到了很多與TastyPie有關的問題,因爲我的模型是高度嵌套的(分層),有很多驗證考慮因素。我轉向了[Django REST框架](http://www.django-rest-framework.org/),並且從不回頭。我並沒有敲開TastyPie,但DRF對我來說似乎更直觀,我從未發現任何複雜的情況,我無法通過重寫API視圖方法來解決。 – Fiver