Przejdę do pytania dotyczącego serializerów w ciągu sekundy, ale przede wszystkim i do wyjaśnienia. Jaki jest cel posiadania zduplikowanych modeli jako Trening/Ukończony trening, Zestaw/Gotowy zestaw, ...?
Dlaczego nie ...
class Workout(models.Model):
#...stuff...
finished = models.DateTimeField(null=True, blank=True)
#...more stuff...
Następnie można po prostu ustawić datę gotowy na trening, kiedy to zrobić.
Teraz, w odniesieniu do pytania. Proponuję myśleć o interakcji użytkownika.Jakie części front-endu próbujesz zapełnić? W jaki sposób dane są powiązane i w jaki sposób użytkownik miałby do niego dostęp?
Powinieneś pomyśleć o parametrach, które wyszukujesz w DRF. Można wysłać datę i oczekują treningi zakończone w określonym dniu:
// This example is done in Angular, but you get the point...
var date= {
'day':'24',
'month':'10',
'year':'2015'
};
API.finishedWorkout.query(date).$promise
.then(function(workouts){
//...workouts is an array of workout objects...
});
Viewset ...
class FinishedWorkoutViewset(viewsets.GenericAPIView,mixins.ListModelMixin):
serializer_class = FinishedWorkOutSerializer
queryset = Workout.objects.all()
def list(self, request):
user = self.request.user
day = self.data['day'];
month = self.data['month'];
year = self.data['year'];
queryset = self.filter_queryset(self.get_queryset().filter(finished__date=datetime.date(year,month,day)).filter(user=user))
page = self.paginate_queryset(queryset)
serializer = self.get_serializer(queryset, many=True)
return response.Response(serializer.data)
I wówczas FinishedWorkoutSerializer może tylko mieć cokolwiek chcesz pola dla danego typu pytanie.
To pozostawia wiele bardzo specyficznych adresów URL, co nie jest wcale takie wspaniałe, ale można użyć konkretnych serializerów dla tych interakcji i jesteś także otwarty na dynamiczną zmianę filtru, w zależności od tego, jakie parametry są self.data
.
Istnieje również prawdopodobieństwo, że możesz chcieć filtrować różnie w zależności od metody, która jest wywoływana, np. Chcesz wyświetlić tylko aktywne ćwiczenia, ale jeśli użytkownik zapyta o konkretne ćwiczenie, chcesz, aby miał do niego dostęp (zauważ, że obiekt ćwiczenia powinien mieć atrybut models.BooleanField
"aktywny").
class ExerciseViewset(viewsets.GenericViewSet, mixins.RetrieveModelMixin, mixins.ListModelMixin):
serializer_class = ExerciseSerializer
queryset = Exercise.objects.all()
def list(self, request):
queryset = self.filter_queryset(self.get_queryset().filter(active=True))
page = self.paginate_queryset(queryset)
serializer = self.get_serializer(queryset, many=True)
return response.Response(serializer.data)
Teraz masz różne obiekty pojawiają się na tym samym URL, w zależności od akcji. Jest trochę bliżej tego, czego potrzebujesz, ale nadal używasz tego samego serializera, więc jeśli potrzebujesz ogromnego obiektu zagnieżdżonego na retrieve()
, dostaniesz też ich kilka, gdy list()
.
Aby zachować listę skrótów i szczegółów zagnieżdżonych, należy użyć różnych serializerów.
Załóżmy, że chcesz wysyłać tylko atrybuty "pk
i name
, gdy są one na liście, ale za każdym razem, gdy ćwiczenie jest sprawdzane, nie możesz przesłać wszystkich powiązanych obiektów" Ustaw "uporządkowanych wewnątrz tablicy" Treningów " ...
# Taken from an SO answer on an old question...
class MultiSerializerViewSet(viewsets.GenericViewSet):
serializers = {
'default': None,
}
def get_serializer_class(self):
return self.serializers.get(self.action, self.serializers['default'])
class ExerciseViewset(MultiSerializerViewSet, mixins.RetrieveModelMixin, mixins.ListModelMixin):
queryset = Exercise.objects.all()
serializers = {
'default': SimpleExerciseSerializer,
'retrieve': DetailedExerciseSerializer
}
Wtedy twój serializers.py może wyglądać trochę jak ...
#------------------Exercise
#--------------------------Simple List
class SimpleExerciseSerializer(serializers.ModelSerializer):
class Meta:
model Exercise
fields = ('pk','name')
#--------------------------Detailed Retrieve
class ExerciseWorkoutExerciseSetSerializer(serializers.ModelSerializer):
class Meta:
model Set
fields = ('pk','name','description')
class ExerciseWorkoutExerciseSerializer(serializers.ModelSerializer):
set_set = ExerciseWorkoutExerciseSetSerializer(many=True)
class Meta:
model WorkoutExercise
fields = ('pk','set_set')
class DetailedExerciseSerializer(serializers.ModelSerializer):
workoutExercise_set = exerciseWorkoutExerciseSerializer(many=True)
class Meta:
model Exercise
fields = ('pk','name','workoutExercise_set')
ja tylko rzucając wokół spraw i atrybutów, które prawdopodobnie nie mają sensu w modelu ruchu, ale Mam nadzieję, że to jest pomocne.
P.S .; Sprawdź, w jaki sposób Java znalazła się na końcu: p "ExcerciseServiceExcersiceBeanWorkoutFactoryFactoryFactory"
gdzie jest kod? – dnozay
Myślałem, że kod nie jest konieczne, ponieważ zmienia NestedRel. do PrimaryKeyRelatedEntities to tylko kilka linii trywialnego kodu w modelu django. A pobieranie na front-end jest prawie takie samo dla obu. – Altoyyr