通过序列化程序在 django rest 框架中收到新评论时如何向 post 作者发送邮件?

How to send mail to the post author when got new comment in django rest framework through serializer?

我正在尝试建立一个 API,学生可以在这里提问,而老师会回答这个问题。对于提问和回答,我使用博客 post 方式。 现在,我的问题是我正在尝试从序列化程序发送邮件。但是当我想检测 post 作者时,我无法做到这一点。我可以发送选定的用户,但不能从模型中发送。 如果有人可以帮助我,那将非常有帮助。非常感谢。

这些是add_question模型和回答问题模型---

    class add_question(models.Model):
    title = models.CharField(max_length=250, blank=False)
    description = models.TextField(blank=True, null=True)
    is_answered = models.BooleanField(default=False)
    is_deleted = models.BooleanField(default=False)
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)
    created_by = models.ForeignKey(User, blank=False, on_delete=models.CASCADE)
    STATUS = (
        ('Published', 'Published'),
        ('Suspended', 'Suspended'),
        ('Unpublished', 'Unpublished'),
    )
    status = models.CharField(choices=STATUS, default='Published', max_length=100)
    RESOLUTION = (
        ('Resolved', 'Resolved'),
        ('Unresolved', 'Unresolved'),
    )
    resolution = models.CharField(choices=RESOLUTION, default='Published', max_length=100)

    def __str__(self):
        return self.title


class add_questionFile(models.Model):
    question = models.ForeignKey(add_question, on_delete=models.CASCADE, related_name='files')
    file = models.FileField('files', upload_to=path_and_rename, max_length=500, null=True, blank=True)




class submit_answer(models.Model):
    description = models.TextField(blank=False, null=False)
    is_deleted = models.BooleanField(default=False)
    rating = models.FloatField(blank=True, null=True)
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)
    question_id = models.ForeignKey(add_question, blank=False, on_delete=models.CASCADE)
    created_by = models.ForeignKey(User, blank=False, on_delete=models.CASCADE)

class submit_answerFile(models.Model):
    answer = models.ForeignKey(submit_answer, on_delete=models.CASCADE, related_name='files')
    file = models.FileField('files', upload_to=path_and_rename, max_length=500, null=True, blank=True)

这些是序列化程序

class add_questionFileSerializer(serializers.ModelSerializer):
    class Meta:
        model = add_questionFile
        fields = ['id', 'file', 'question']
        extra_kwargs = {
        'question': {'required': False},
        }

class add_questionSerializer(serializers.ModelSerializer):
    files = add_questionFileSerializer(many=True, required=False)

    class Meta:
        model = add_question
        fields = ('id', 'created_by', 'title', 'description', 'files', 'is_answered')

    def create(self, validated_data):        
        question = add_question.objects.create(**validated_data)
        try:
            # try to get and save images (if any)
            files_data = dict((self.context['request'].FILES).lists()).get('files', None)
            for file in files_data:
                add_questionFile.objects.create(question=question, file=file)
        except:
            # if no images are available - create using default image
            add_questionFile.objects.create(question=question)
        send_mail(
            'Question {} has been asked'.format(question.pk),
            'A new question has been asked . DATA: {}'.format(validated_data),
            'noreply@suflek.com',
            ['testuser@gmail.com', 'testuser1@gmail.com'],
            fail_silently=False,
        )
        send_mail(
            'Your question has been submitted'.format(question.pk),
            'Your asked question has been submitted to SUFLEK. We will reach with solution soon. DATA: {}'.format(validated_data),
            'noreply@test.com',
            ['testuser2@gamil.com'],
            fail_silently=False,
        )
        return question


class submit_answerFileSerializer(serializers.ModelSerializer):
    class Meta:
        model = submit_answerFile
        fields = ['id', 'file', 'answer']
        extra_kwargs = {
        'answer': {'required': False},
        }

class submit_answerSerializer(serializers.ModelSerializer):
    files = submit_answerFileSerializer(many=True, required=False)

    class Meta:
        model = submit_answer
        fields = ('id', 'question_id', 'created_by', 'description', 'files')

    def create(self, validated_data):

        answer = submit_answer.objects.create(**validated_data)
        try:
            # try to get and save images (if any)
            files_data = dict((self.context['request'].FILES).lists()).get('files', None)
            for file in files_data:
                submit_answerFile.objects.create(answer=answer, file=file)
        except:
            # if no images are available - create using default image
            submit_answerFile.objects.create(answer=answer)
        
        send_mail(
            'Your asked question has been answered',
            'Here is the message. DATA: {}'.format(validated_data),
            'noreply@test.com',
            ['testuser@gmail.com'], # need to add the user who asked the question
            fail_silently=False,
        )
        return answer

这些是观点

    # ask question POST and GET API
class add_questionAPIView(generics.ListCreateAPIView):
    permission_classes = (permissions.IsAuthenticated,)
    queryset = add_question.objects.all()
    serializer_class = add_questionSerializer
    
    #single question GET API
class all_questionsDetailsAPIView(generics.RetrieveUpdateDestroyAPIView):
    permission_classes = (permissions.IsAuthenticated,)
    queryset = add_question.objects.all()
    serializer_class = add_questionSerializer

# comment POST and GET API
class submitanswerAPIView(generics.ListCreateAPIView):
    permission_classes = (permissions.IsAuthenticated,)
    queryset = submit_answer.objects.all()
    serializer_class = submit_answerSerializer

    #single comment GET API
class submitanswerDetailsAPIView(generics.RetrieveUpdateDestroyAPIView):
    permission_classes = (permissions.IsAuthenticated,)
    queryset = submit_answer.objects.all()
    serializer_class = submit_answerSerializer

如果需要任何其他信息,请告诉我。我不是那么专业,都是通过学习来做的。 再次提前致谢。

因为 question_id 是链接到 add_question 模型的外键,并且 add_question 有一个 created_by 字段,您可以使用 serializerModelField 添加另一个序列化器的字段,像这样:

user_email = serializers.SerializerMethodField('get_user_email')

class Meta:
    model = submit_answer
    fields = ('id', 'question_id', 'created_by', 'description', 'files', 'user_email')

def get_user_email(self, obj):
    return obj.question_id.created_by.email

在函数 get_user_email 中,您将访问 User 的电子邮件,创建 add_question 对象,该对象由 ForeignKey=question_id 表示,存储在 submit_answer 对象

我也和上面的解决方案差不多解决了这个问题。但想与大家分享,也为了我以后的使用。

刚刚修改了序列化器的send_mail()to_email部分,通过外键调用

在 add_question 我在一次操作中使用了两封电子邮件,而 submit_answer 一封。 谢谢,我希望这能对你有所帮助。

#add_questionFileSerializer

    send_mail(
                'Question {} has been asked'.format(question.pk),
                'A new question has been asked . DATA: {}'.format(validated_data),
                'noreply@email.com',
                ['email1@email.com', 'email2@email.com'],
                fail_silently=False,
            )
            send_mail(
                'Your question has been submitted'.format(question.pk),
                'Your asked question has been submitted to SUFLEK. We will reach with solution soon. DATA: {}'.format(validated_data),
                'noreply@email.com',
                # [to_email],
                ['{}'.format(question.created_by)],
                fail_silently=False,
            )


#submit_answerSerializer
    send_mail(
            # subject
            'Your asked question has been answered',
            # body
            'Here is the message. DATA: {}'.format(validated_data),
            # from mail
            'noreply@email.com',
            # to mail
            ['{}'.format(answer.question_id.created_by)], //this line I got my solution
            fail_silently=False,
        )