Djoser เปลี่ยนภาษาอีเมล

Nov 01 2020

มีวิธีเปลี่ยนอีเมลที่ส่งใน djoser ตามภาษาของอินสแตนซ์ผู้ใช้หรือไม่ ฉันพบคำถามนี้ฉันจะระบุภาษาของอีเมลที่ต้องการส่งอย่างชัดเจนได้อย่างไร แต่ดูเหมือนจะไม่ใช่ตัวเลือกใน djoser เวอร์ชันล่าสุดเนื่องจากไม่มีมุมมองสำหรับแต่ละการกระทำอีกต่อไป (การเปิดใช้งานการรีเซ็ตรหัสผ่าน ฯลฯ ) หรือฉันไม่ทราบวิธีการทำงาน นอกจากนี้ฉันได้ลองใช้คลาส UserViewSet และใช้การแปล แต่ฉันไม่รู้ว่านี่เป็นวิธีการทำหรือไม่และจะระบุ urls ทั้งหมดของ djoser ได้อย่างไร

class UserViewSet(djoser_view.UserViewSet):
    def perform_create(self, serializer):
        user = serializer.save()
        signals.user_registered.send(
            sender=self.__class__, user=user, request=self.request
        )

        context = {"user": user}
        to = [get_user_email(user)]
        language = user.language or 'en-us'
        with translation.override(language):
            if settings.SEND_ACTIVATION_EMAIL:
                settings.EMAIL.activation(self.request, context).send(to)
            elif settings.SEND_CONFIRMATION_EMAIL:
                settings.EMAIL.confirmation(self.request, context).send(to)

    def perform_update(self, serializer):
        super().perform_update(serializer)
        user = serializer.instance
        language = user.language or 'en-us'
        with translation.override(language):
            if settings.SEND_ACTIVATION_EMAIL:
                context = {"user": user}
                to = [get_user_email(user)]
                settings.EMAIL.activation(self.request, context).send(to)


    @action(["post"], detail=False)
    def activation(self, request, *args, **kwargs):
        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        user = serializer.user
        user.is_active = True
        user.save()

        signals.user_activated.send(
            sender=self.__class__, user=user, request=self.request
        )

        language = user.language or 'en-us'
        with translation.override(language):
            if settings.SEND_CONFIRMATION_EMAIL:
                context = {"user": user}
                to = [get_user_email(user)]
                settings.EMAIL.confirmation(self.request, context).send(to)

        return Response(status=status.HTTP_204_NO_CONTENT)

ใครมีคำแนะนำหรือเคยทำมาแล้วบ้าง?

คำตอบ

TomWojcik Dec 02 2020 at 18:30

แน่ใจนะว่าทำได้!

คุณระบุการดำเนินการที่ส่งอีเมลได้อย่างถูกต้อง

    @action(["post"], detail=False)
    def activation(self, request, *args, **kwargs):
        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        user = serializer.user
        user.is_active = True
        user.save()

        signals.user_activated.send(
            sender=self.__class__, user=user, request=self.request
        )

        if settings.SEND_CONFIRMATION_EMAIL:
            context = {"user": user}
            to = [get_user_email(user)]
            settings.EMAIL.confirmation(self.request, context).send(to)

ดังนั้นหลังจากคลาสย่อยUserViewSetคุณสามารถระบุชื่อเทมเพลตในactivationการดำเนินการได้

        if settings.SEND_CONFIRMATION_EMAIL:
            context = {"user": user}
            to = [get_user_email(user)]
            kwargs = {"request": self.request, "context": context}
            if user.country == "Country1":
                kwargs["template_name"] = "email/country1/activation.html"
            settings.EMAIL.confirmation(**kwargs)).send(to)

Djoser ใช้templated-mailเพื่อสร้างเนื้อหาเมล

แต่อย่างที่คุณเห็นuserเอนทิตีถูกส่งผ่านไปในบริบท ดังนั้นฉันขอแนะนำให้ปรับแต่งการตั้งค่าของคุณเล็กน้อยและทำในชั้นเรียนที่รับผิดชอบในการสร้างอีเมลนี้

ในไฟล์ app/email.py

class CountryActivationMail(ActivationEmail):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        if self.context.user.country == "Country1":
            self.template_name = "email/country1/activation.html"

และตั้งค่าCountryActivationMailในการตั้งค่า djoser ตามที่อธิบายไว้ในเอกสาร