gpt4 book ai didi

python - 使用 Django Rest Framework 在 ModelViewSet 中使用自定义函数

转载 作者:太空宇宙 更新时间:2023-11-03 13:59:10 25 4
gpt4 key购买 nike

Django 2.0、Python 3.6、Django Rest Framework 3.8

我对 Django Rest Framework 还是很陌生,我正在努力思考在 View 集中使用函数的逻辑(如果这是包含函数的正确位置)。

基本上,当用户向此特定 View 集中的 api 发布内容时,我想发送一封电子邮件。我尝试使用 send_mail 函数,但没有成功。我有以下基于类的 View :

class SendInviteView(viewsets.ModelViewSet):
queryset = models.Message.objects.all()
serializer_class = serializers.MessageSerializer

@action(methods=['post'], detail=True)
def send_the_mail(self, request):
send_mail(
'Invitation',
'Try our app!',
'exampleemail@gmail.com',
['examplerecipient@gmial.com'],
fail_silently=False,
)

[Model 和 Serializer 非常基础,我认为这个问题的上下文不需要,基本上只是一个 EmailField()。我最终计划使用该电子邮件字段的输入来替换 examplerecipient@gmail.com,但现在我只想了解如何向 View 集添加功能]

这会导致在运行 python manage.py check 时出错

我通过 sendgrid 设置了我的电子邮件客户端,并且能够成功地向要求通过 rest-auth 重置密码的用户发送电子邮件,但我不明白如何发送电子邮件在该上下文之外工作。

非常感谢任何帮助。

最佳答案

经过讨论,我想出了以下几点。

from django.conf import settings
from django.core.mail import send_mail
from django.db import models
from rest_framework import serializers, viewsets, routers, mixins
from rest_framework.response import Response


class Message(models.Model):
sender = models.ForeignKey(settings.AUTH_USER_MODEL)
recipient = models.EmailField()


class MessageSerializer(serializers.ModelSerializer):
message = serializers.CharField(write_only=True)

class Meta:
model = Message
fields = ['recipient', 'message']

def create(self, validated_data):
message = validated_data.pop('message')
message_obj = super().create(validated_data)
send_mail(
'Invitation',
message,
'exampleemail@gmail.com',
[message_obj.recipient]
)
return message_obj

class SendInviteView(mixins.CreateModelMixin, viewsets.GenericViewSet):
serializer_class = MessageSerializer

def perform_create(self, serializer):
serializer.save(sender=self.request.user)


router = routers.DefaultRouter()
router.register('send_invite', SendInviteView, base_name='send_invite')
urlpatterns = router.urls

让我们分解一下。

如果你想存储发件人,你需要 ForeignKey 到你的模型中的 User

对于序列化器,您需要手动添加message 字段,因为它在您的模型中不存在,但用户应该提交它。我们将其设置为只写,因为这个序列化器还将用于将创建的 Message 序列化回用户以进行响应,而 Message 没有 message 字段。此序列化程序还将从 Message 模型自动为 recipient 生成字段。

然后我们在这个序列化器中重写 create,所以每当使用它创建新的 Message 时,它都会发送一封电子邮件。它调用 super().create(..)Message 实际保存到数据库中,然后发送一封电子邮件。我们使用 .pop()validated_data 中删除 message,因为 Message 不包含这样的字段。

对于 View ,我们不需要 ModelViewSet 提供的全部内容。它增加了创建、读取、更新和删除 (CRUD) 您的 Message 的能力,这实际上并不需要。您所需要的只是简单的 Create,它根据 HTTP 请求转换为 POSTGenericViewSetCreateModelMixin 正是我们想要的东西(实际上 ModelViewSet 只是有更多的 mixins)。来自用户的数据将由序列化程序验证,然后 perform_create 方法将被调用。我们将 sender=self.request.user 传递给 serializer.save() 因为我们需要将 sender 保存到 Message, 而sender字段其实不在数据中,是当前登录的用户。serializer.save() 将运行我们的 MessageSerializer.create() 所以我们很高兴。

请注意,此内容仅适用于登录用户,因为我们需要以某种方式填充数据库中的 sender 字段,因此添加

是正确的
class SendInviteView(mixins.CreateModelMixin, viewsets.GenericViewSet):
permission_classes = [IsAuthenticated]
....

因此只有经过身份验证的用户才能发出请求。希望这会为您澄清事情。最好的问候)

关于python - 使用 Django Rest Framework 在 ModelViewSet 中使用自定义函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51273784/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com