django 在DRF中创建对象时如何更改相关对象

vc6uscn9  于 2023-08-08  发布在  Go
关注(0)|答案(2)|浏览(134)

我想在创建预订时更改Book对象中的is_available字段。我找到了一种方法,我在这里粘贴,但这种挖掘请求看起来很混乱,所以对于像drf这样成熟的框架来说,可能有更好的方法来做到这一点。
所以我有serializer.py

class BookSerializer(serializers.HyperlinkedModelSerializer):
    class Meta:
        model = BookModel
        fields = ["number", "title", "author", "is_available"]

class ReservationSerializer(serializers.HyperlinkedModelSerializer):
    class Meta:
        model = ReservationModel
        fields = ["reserved_by", "book", "started_at", "valid_until"]

字符串
以及views.py

class BookViewSet(viewsets.ModelViewSet):
    queryset = BookModel.objects.all()
    serializer_class = BookSerializer
    permission_classess = []

class ReservationViewSet(viewsets.ModelViewSet):
    queryset = ReservationModel.objects.all()
    serializer_class = ReservationSerializer
    permission_classess = []

    def perform_create(self, request, *args, **kwargs):
        super().perform_create(request, *args, **kwargs)
        book = BookModel.objects.get(pk=request.data.serializer.instance.book_id)
        book.is_available = False
        book.save()


我张贴了我所做的,请教我做得更好-正确的方式

3wabscal

3wabscal1#

  • .perform_create()* 方法看起来像这样:
def perform_create(self, serializer):
    serializer.save()

字符串
它唯一的参数是 serializer,而不是 request,因为它在代码中没有 *args和**kwargs。你可能把它和 .create() 方法搞混了。

def create(self, request, *args, **kwargs):
    serializer = self.get_serializer(data=request.data)
    serializer.is_valid(raise_exception=True)
    self.perform_create(serializer)
    headers = self.get_success_headers(serializer.data)
    return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers)


如果你想在perform_create方法中添加逻辑,你应该这样做:

def perform_create(self, serializer):
    reservation = serializer.save()
    book = reservation.book 
    book.is_available = False
    book.save()

9q78igpj

9q78igpj2#

在创建Reservation时,为了更好更有组织地更改Book对象的is_available字段,您可以使用Django信号。信号允许解耦的应用程序在应用程序中的其他地方发生某些操作时得到通知。
以下是如何使用信号来实现这一点:
1.在app目录中创建一个名为signals.py的文件:

from django.db.models.signals import post_save
from django.dispatch import receiver
from .models import ReservationModel

@receiver(post_save, sender=ReservationModel)
def update_book_availability(sender, instance, **kwargs):
    if instance.pk:
        book = instance.book
        book.is_available = False
        book.save()

字符串
1.在apps.py文件中,添加以下行:

from django.apps import AppConfig

class YourAppConfig(AppConfig):
    name = 'your_app_name'

    def ready(self):
        import your_app_name.signals


1.从ReservationViewSet中删除perform_create方法,因为您不再需要它:

class ReservationViewSet(viewsets.ModelViewSet):
    queryset = ReservationModel.objects.all()
    serializer_class = ReservationSerializer
    permission_classes = []


使用此实现,每当创建ReservationModel对象时,update_book_availability信号将自动触发,并且它将相应地更新关联BookModelis_available字段。这有助于保持逻辑分离,并使您的代码更具可维护性和可伸缩性。

相关问题