2016-04-20 12 views
8

Więc mam serializatora, który wygląda takDjango-REST serializer: queryset nie filtruje PrimaryKeyRelatedField wyniki

class BuildingsSerializer(serializers.ModelSerializer): 
    masterlisting_set = serializers.PrimaryKeyRelatedField(many=True, 
            queryset=Masterlistings.objects.all()) 

i działa świetnie

serializer = BuildingsSerializer(Buildings.objects.get(pk=1)) 
serializer.data 

produkuje

OrderedDict([ 
    ("masterlistings_set", [ 
     "0a06e3d7-87b7-4526-a877-c10f54fa5bc9", 
     "343643ac-681f-4597-b8f5-ff7e5be65eef", 
     "449a3ad2-c76c-4cb8-bb86-1be72fafcf64", 
    ]) 
]) 

ale jeśli zmienię zestaw zapytań w serializatorze na

class BuildingsSerializer(serializers.ModelSerializer): 
    masterlistings_set = serializers.PrimaryKeyRelatedField(many=True, queryset=[]) 

Wciąż otrzymuję ten sam dokładny wynik z powrotem.

OrderedDict([ 
    ("masterlistings_set", [ 
     "0a06e3d7-87b7-4526-a877-c10f54fa5bc9", 
     "343643ac-681f-4597-b8f5-ff7e5be65eef", 
     "449a3ad2-c76c-4cb8-bb86-1be72fafcf64", 
    ]) 
]) 

Czy to ma się dziać? Czy nieprawidłowo używam zapytań? Użyłem [] jako prostego przykładu, aby pokazać, że bez względu na to, co wprowadzę, nic się nie zmieni.

Proszę Każdy wgląd byłby nieoceniony

Należy zauważyć, że masterlistings ma klucz podstawowy relacji wskazujący na budynkach. A więc masterlisting należy do budynku.

Odpowiedz

6

Jak wskazano przez @zymud, argument queryset w PrimaryKeyRelatedField służy do sprawdzania poprawności danych wejściowych pola w celu utworzenia nowych wpisów. Innym rozwiązaniem dla odfiltrowanie masterlistings_set jest użycie serializers.SerializerMethodField() w następujący sposób:

class BuildingsSerializer(serializers.ModelSerializer): 
    masterlisting_set = serializers.SerializerMethodField() 

    def get_masterlisting_set(self, obj): 
     return MasterListing.objects.filter(building=obj).values_list('pk',flat=True) 
+0

Niesamowite, akceptuję tę odpowiedź, ponieważ jest to czystsze z dwóch! –

+0

Jesteś święty (12:04) – dps

2

queryset w pokrewnym polu ogranicza tylko akceptowalne wartości. Tak więc z queryset=[] nie będzie można dodawać nowych wartości do masterlisting_set ani tworzyć nowych Buildings.

AKTUALIZACJA. Jak korzystać z queryset filtrowania

To jest trochę bi trudne - trzeba przepisać ManyRelatedField i many_init metodę w swojej RelatedField.

# re-define ManyRelatedField `to_representation` method to filter values 
# based on queryset 
class FilteredManyRelatedField(serializers.ManyRelatedField): 
    def to_representation(self, iterable): 
     iterable = self.child_relation.queryset.filter(
      pk__in=[value.pk for value in iterable]) 
     return super(FilteredManyRelatedField, self).to_representation(iterable) 


# use overridden FilteredManyRelatedField in `many_init` 
class FilteredPrimaryKeyRelatedField(serializers.PrimaryKeyRelatedField): 
    @classmethod 
    def many_init(cls, *args, **kwargs): 
     kwargs['child_relation'] = cls(queryset=kwargs.pop('queryset')) 
     return FilteredManyRelatedField(*args, **kwargs) 
+0

widzę, dziękuję za info. Czy mimo to używasz go do odfiltrowania informacji otrzymanych z serializera? –

+1

Zaktualizowałem moją odpowiedź. – zymud

+0

Wow! Dziękuję za Twój czas! –