2017-07-26 18 views
0

シリアライザフィールドからDjango QuerySetを注文するにはどうすればよいですか?フィールドが複雑すぎるためannotateを使用してQuerySetを注文することができず、モデルに値を格納することもできません。シリアライザフィールドからdjango rest framework querysetを注文するには?

編集:

シリアライザ

class DrinkListModelSerializer(serializers.ModelSerializer): 
    count_need = serializers.SerializerMethodField() 
    url = drink_detail_url 

    class Meta: 
     model = Drink 
     fields = [ 
      'name', 
      'count_need', 
      'thumbnail', 
      'url' 
     ] 

    def get_count_need(self, obj): 
     drink_ingredient_qs = obj.ingredients.all() 
     user = self.context['request'].user 
     user_qs = User.objects.filter(username=user.username) 
     if user_qs.exists() and user_qs.count() == 1: 
      user_obj = user_qs.first() 
      user_ingredient_qs = user_obj.ingredient_set.all() 
      return (user_ingredient_qs & drink_ingredient_qs).count() 
     return 0 

モデル:それはであることから、現在、私はタイムスタンプでクエリセットを注文してい

class Drink(models.Model): 
    name    = models.CharField(max_length = 1000, null=True, blank=True) 
    ingredients   = models.ManyToManyField(Ingredient, blank=True) 
    user    = models.ManyToManyField(settings.AUTH_USER_MODEL, blank=True) 

class Ingredient(models.Model): 
    name    = models.CharField(max_length = 1000) 
    ingredient_category = models.ForeignKey(Category, null=True, blank=True) 
    slug    = models.SlugField(max_length=255, unique=True) 
    user    = models.ManyToManyField(settings.AUTH_USER_MODEL, blank=True) 

ビュー

class DrinkListAPIView(ListAPIView): 
serializer_class = DrinkListModelSerializer 
pagination_class = LargeResultsSetPagination 
permission_classes = [AllowAny] 

def get_queryset(self, *args, **kwargs): 
    user = self.request.user 
    qs = Drink.objects.all() 
    userQuery = self.request.GET.get('user') 
    query = self.request.GET.get("q") 
    filters = self.request.GET.getlist('filter') 
    if query: 
     qs = qs.filter(name__icontains=query) 
    elif filters: 
     qs = qs.filter(playlist__name__iexact=filters[0]) 
     for filter in filters[1:]: 
      qs = qs | Drink.objects.filter(playlist__name__iexact=filter) 
    elif userQuery and user.is_authenticated(): 
     qs = qs.filter(user=user) 
    return qs.order_by('-timestamp') 

自分自身をモデル化する私はシリアライザの一部である 'count_need'によってそれを注文する必要があります。私はqs = qs.annotate(count_need=Count('ingredients' & user_ingredient_qs)).order_by(count_need)のようなことをしようとしましたが、これは明らかに「成分」はここの文字列であり、ドリンクの成分のクエリーセットではないからです。

+1

あなたは、シリアライザをあなたのモデルを提供し、してください見ることができます。 – mattjegan

+0

私はちょうど元のポストを編集しました –

答えて

0

うまくいくかもしれない一つの方法は、リストのシリアライザにto_representationを実装してカスタマイズすることです。

def to_representation(self, data): 
    iterable = data.all() if isinstance(data, models.Manager) else data 

    iterable = sorted(iterable, key=lambda x: x.count_need) 

    return [ 
     self.child.to_representation(item) for item in iterable 
    ] 
+0

ええと私はそれを試して、私は "Typeerror:ドリンクオブジェクトは、ソートされた行、任意の提案に反復可能ではありませんか? –

+0

シリアライザのインス​​タンスを1つだけ渡しているようですが、シリアライザの初期化を呼び出すときに 'many = True'を追加してみてください。 – mattjegan

関連する問題