django-rest-framework
#django-rest-framework
Вопрос:
Цель состоит в том, чтобы показать уроки, которые были вставлены только текущим пользователем, а именно: user_author_lesson. user_author_lesson на самом деле является внешним ключом к модели пользователя. Я хочу запросить поле имени пользователя в наборе запросов сериализатора. Или, может быть, есть другой способ реализовать это. Спасибо.
Модели
from django.contrib.auth.models import User
# from django.utils import timezone
from datetime import date
class Student(models.Model):
first_name = models.CharField(max_length=50)
last_name = models.CharField(max_length=50)
information = models.TextField(blank=True)
user_author_student = models.ForeignKey(
User, null=True, on_delete=models.CASCADE)
objects = models.Manager() # default manager
class Meta:
ordering = ('-first_name',)
def __str__(self):
return self.first_name
class Lesson(models.Model):
options = (
('paid', 'Paid'),
('not paid', 'Not Paid'),
)
student = models.ForeignKey(
Student, on_delete=models.CASCADE, related_name='lessons')
paid = models.CharField(
max_length=10, choices=options, default='not paid')
title = models.CharField(max_length=50)
task1 = models.CharField(max_length=50)
description1 = models.TextField(blank=True)
task2 = models.CharField(max_length=50)
description2 = models.TextField(blank=True)
user_author_lesson = models.ForeignKey(
User, null=True, on_delete=models.CASCADE)
lesson_date = models.DateField(default=date.today, null=False)
objects = models.Manager() # default manager
class Meta:
ordering = ('-lesson_date',)
def __str__(self):
return '%s: %s %s %s' % (self.student, self.title, self.lesson_date, self.paid)
число просмотров
from django.http import request
from rest_framework import generics
from rest_framework.serializers import Serializer
from private_models.models import Lesson, Student
from .serializers import LessonSerializer, LessonDetailSerializer, StudentDetailSerializer, StuSerializer, CreateLessonSerializer,DeleteLessonSerializer
from rest_framework.permissions import SAFE_METHODS, DjangoModelPermissions, BasePermission, AllowAny
from django.shortcuts import get_object_or_404
class LessonUserWritePermission(BasePermission):
message = 'editing lesson is restricted to the authors only'
def has_object_permission(self, request, view, obj):
if request.method in SAFE_METHODS:
return True
return obj.user_author_lesson == request.user
class LessonList(generics.ListCreateAPIView):
# permission_classes = [DjangoModelPermissions]
permission_classes = [AllowAny]
queryset = Lesson.objects.all()
#queryset = Lesson.objects.filter(user_author_lesson=request.user.username).all()
serializer_class = LessonSerializer
#print(self.request.user)
#def get_queryset(self):
# print(queryset.objects.filter(user_author_lesson=self.request.user))
# return Lesson.objects.filter(user_author_lesson=).all()
class StuDetail(generics.RetrieveUpdateDestroyAPIView):
permission_classes = [AllowAny]
queryset = Student.objects.all()
serializer_class = StudentDetailSerializer
# def get_object(self, queryset=None, **kwargs):
# item = self.kwargs.get('pk')
# return get_object_or_404(Student, pk=item)
class StuList(generics.ListCreateAPIView):
# permission_classes = [DjangoModelPermissions]
permission_classes = [AllowAny]
queryset = Student.objects.all()
serializer_class = StuSerializer
class LessonDetail(generics.RetrieveUpdateDestroyAPIView):
# class LessonDetail(generics.RetrieveUpdateDestroyAPIView, LessonUserWritePermission):
# the above line is to use when i fix the user permissions!!!
# permission_classes = [LessonUserWritePermission]
permission_classes = [AllowAny]
queryset = Lesson.objects.all()
serializer_class = LessonDetailSerializer
class CreateLesson(generics.CreateAPIView):
permission_classes = [AllowAny]
queryset = Lesson.objects.all()
serializer_class = CreateLessonSerializer
class DeleteLesson(generics.DestroyAPIView):
permission_classes =[AllowAny]
queryset = Lesson.objects.all()
serializer_class = DeleteLessonSerializer
сериализаторы
from rest_framework import serializers, fields
from private_models.models import Lesson, Student
class LessonSerializer(serializers.ModelSerializer):
student = serializers.SerializerMethodField()
user_author_lesson = serializers.StringRelatedField(read_only=True)
# def __init__(self, *args, **kwargs):
# super().__init__(*args, **kwargs)
# try:
# if self.context['request'].method in ['GET']:
# self.fields['student'] = serializers.SerializerMethodField()
# except KeyError:
# pass
class Meta:
model = Lesson
fields = ('id', 'student', 'title', 'lesson_date',
'paid', 'user_author_lesson')
def get_student(self, obj):
return obj.student.first_name
def post():
pass
class LessonDetailSerializer(serializers.ModelSerializer):
class Meta:
model = Lesson
fields = ('id', 'student', 'title', 'task1', 'description1',
'task2', 'description2', 'lesson_date', 'paid',)
class StudentDetailSerializer(serializers.ModelSerializer):
lessons = LessonSerializer(many=True, read_only=True)
class Meta:
model = Student
fields = ('first_name', 'last_name', 'information', 'lessons')
class StuSerializer(serializers.ModelSerializer):
user_author_student = serializers.StringRelatedField(read_only=True)
class Meta:
model = Student
# lessons = LessonDetailSerializer(many=True)
fields = ('id', 'first_name', 'last_name',
'information', 'user_author_student')
class CreateLessonSerializer(serializers.ModelSerializer):
# student = serializers.SerializerMethodField()
student_id = serializers.IntegerField(write_only=False)
class Meta:
model = Lesson
fields = ('student_id', 'title', 'task1', 'description1',
'task2', 'description2', 'lesson_date', 'paid',)
class DeleteLessonSerializer(serializers.ModelSerializer):
class Meta:
model = Lesson
fields =('student_id', 'title', 'task1', 'description1',
'task2', 'description2', 'lesson_date', 'paid',)
Ответ №1:
Напишите LessonsViewset и определите метод get_queryset следующим образом:
class LessonViewsets(viewsets.ModelViewset):
queryset = Lesson.objects.all()
serializer_class = LessonSerializer
permission_classes = []
def get_queryset(self, *args, **kwargs):
super().get_queryset()
student_id = Student.objects.get(
users_lessons = Lesson.objects.select_related.("student").filter(student=self.request.user.id)
return users_lessons
Наборы представлений из DRF очень эффективны. Однако вы можете использовать ListCreateAPIView; просто определите метод get_queryset, чтобы возвращать только уроки, связанные с аутентифицированным пользователем.
Комментарии:
1. Спасибо. Итак, мне нужно создать класс UserSerializer?
2. Простите, это должны быть LessonSerializers, а не UseeSerializer. Вы знаете, как настроить сериализатор? Дайте мне знать
3. мой get_queryset должен фильтровать user_author_lesson, и я не смог его реализовать, потому что внешний ключ не имеет related_name .
4. Я вижу. Затем сделайте это: перейдите к модели вашего урока; в вашем уроке user_author выполните: user_author урок = модели. ForeignKey(User, related_name=»урок», on_delete=модели. КАСКАД)
5. текущий пользователь — это user_author_lesson, и я хочу отображать только его вставки данных, означающие введенные им уроки. Студенты не имеют значения. Итак, я попытался создать get_queryset, но как его отфильтровать? (Я привык к flask ..) Я не могу фильтровать по user_author_lesson, потому что он ничего не возвращает и говорит, что ожидает целое число, если я помню.
Ответ №2:
Существует более простой способ выполнения обратных запросов.
По умолчанию django
позволяет выполнять обратные запросы, используя имена, связанные с умолчанию, которые есть <ModelName>_set
.
например, если вы хотите fetch all the lessons
против некоторых user
.
user_instance.lesson_set.all()
Попробуйте переписать LessonList
класс View как:
class LessonList(generics.ListCreateAPIView):
# permission_classes = [DjangoModelPermissions]
permission_classes = [AllowAny]
queryset = Lesson.objects.all()
serializer_class = LessonSerializer
def get_queryset(self, *args, **kwargs):
return self.request.user.lesson_set.all()
В документации Django есть более полезные примеры.
Комментарии:
1. Спасибо. Я попробую. Я также столкнулся с функцией preform_create, которая, я думаю, мне нужна для определения пользователя, который вошел в урок.