Skip to content

Commit c8eba73

Browse files
committed
refactoring 1
1 parent 43bf8be commit c8eba73

7 files changed

Lines changed: 95 additions & 67 deletions

File tree

mailing/constants.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
default_mailing_schema = {
2+
"key_with_default_value": {
3+
"title": "Ключ с стандартным значением.",
4+
"default": "Значение",
5+
},
6+
"default_key": {"title": "Просто ключ."},
7+
}

mailing/models.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,18 @@
33

44
from django.core.validators import FileExtensionValidator
55
from django.db import models
6+
from .constants import default_mailing_schema
67

78

89
def get_template_path(instance, filename):
910
ext = filename.split(".")[-1]
1011
filename = "%s.%s" % (uuid.uuid4(), ext)
11-
return os.path.join("templates/email", filename)
12+
return os.path.join("templates/mailing/emails", filename)
1213

1314

1415
class MailingSchema(models.Model):
1516
name = models.CharField(max_length=100, unique=True)
16-
schema = models.JSONField(default=dict, null=True, blank=True)
17+
schema = models.JSONField(default=default_mailing_schema, null=True, blank=True)
1718
template = models.FileField(
1819
upload_to=get_template_path,
1920
validators=[FileExtensionValidator(allowed_extensions=["html"])],

mailing/urls.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,15 @@
11
from django.urls import path
22

3-
from mailing.views import MailingSchemaView, template_fields, SendMailView
3+
from mailing.views import TemplateFieldsView, MailingSchemaView, SendMailView
44

55
app_name = "mailing"
66

77
urlpatterns = [
88
path("mail", MailingSchemaView.as_view()),
9-
path("template_fileds/<int:schema_id>/", template_fields, name="template_fields"),
9+
path(
10+
"template_fileds/<int:schema_id>/",
11+
TemplateFieldsView.as_view(),
12+
name="template_fields",
13+
),
1014
path("send_email", SendMailView.as_view(), name="send_mail"),
1115
]

mailing/utils.py

Lines changed: 45 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -9,46 +9,51 @@
99
from users.models import CustomUser
1010

1111

12-
class MailSender:
13-
@staticmethod
14-
def send(
15-
users: django.db.models.QuerySet | List[CustomUser],
16-
subject: str,
17-
template_path: str,
18-
template_context: Union[
19-
Dict,
20-
List,
21-
] = None,
22-
connection=None,
23-
) -> None:
24-
"""
25-
Begin mailing to specified users, sending rendered template with template_text arg.
26-
Throws an error if template render is unsuccessful.
27-
Args:
28-
users: - The list of users who should receive the email.
29-
template_path: str of template_path
30-
subject: Subject of mail.
31-
template_context: Context for template render.
32-
connection: Connection to mail backend
33-
"""
34-
if template_context is None:
35-
template_context = {}
12+
def send_mail(
13+
user: CustomUser,
14+
subject: str,
15+
template_path: str,
16+
template_context: Union[
17+
Dict,
18+
List,
19+
] = None,
20+
connection=None,
21+
):
22+
return send_mails_mass([user], subject, template_path, template_context, connection)
3623

37-
template_path = pathlib.Path(template_path).absolute()
24+
25+
def send_mails_mass(
26+
users: django.db.models.QuerySet,
27+
subject: str,
28+
template_path: str,
29+
template_context: Union[
30+
Dict,
31+
List,
32+
] = None,
33+
connection=None,
34+
) -> None:
35+
"""
36+
Begin mailing to specified users, sending rendered template with template_text arg.
37+
Throws an error if template render is unsuccessful.
38+
Args:
39+
users: - The list of users who should receive the email.
40+
template_path: str of template_path
41+
subject: Subject of mail.
42+
template_context: Context for template render.
43+
connection: Connection to mail backend
44+
"""
45+
if template_context is None:
46+
template_context = {}
47+
template_path = pathlib.Path(template_path).absolute()
48+
connection = connection or mail.get_connection()
49+
messages = []
50+
for user in users:
51+
template_context["user"] = user
3852
html_msg = render_to_string(template_path, template_context)
3953
plain_msg = render_to_string(template_path, template_context)
40-
emails = [user.email for user in users]
41-
data = [
42-
(subject, plain_msg, None, [recipient_email], html_msg)
43-
for recipient_email in emails
44-
]
45-
46-
connection = connection or mail.get_connection()
47-
messages = []
48-
for subject, message, sender, recipient, html_msg in data:
49-
msg = EmailMultiAlternatives(
50-
subject, message, sender, recipient, connection=connection
51-
)
52-
msg.attach_alternative(html_msg, "text/html")
53-
messages.append(msg)
54-
return connection.send_messages(messages)
54+
msg = EmailMultiAlternatives(
55+
subject, plain_msg, None, [user.email], connection=connection
56+
)
57+
msg.attach_alternative(html_msg, "text/html")
58+
messages.append(msg)
59+
return connection.send_messages(messages)

mailing/views.py

Lines changed: 29 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
from rest_framework.views import APIView
55

66
from users.models import CustomUser
7-
from .utils import MailSender
7+
from .utils import send_mails_mass
88
from .models import MailingSchema
99

1010

@@ -15,12 +15,12 @@ def post(self, request):
1515
subject = request.POST["subject"]
1616
mail_schema = MailingSchema.objects.get(pk=schema_id)
1717
context = {}
18-
for key in mail_schema.schema:
19-
key_in_post = "field-" + key
18+
for variable_name in mail_schema.schema:
19+
key_in_post = "field-" + variable_name
2020
if key_in_post in request.POST:
21-
context[key] = request.POST[key_in_post]
21+
context[variable_name] = request.POST[key_in_post]
2222
users_to_send = CustomUser.objects.filter(pk__in=users)
23-
MailSender.send(users_to_send, subject, mail_schema.template.path)
23+
send_mails_mass(users_to_send, subject, mail_schema.template.path)
2424
return JsonResponse({"detail": "ok"})
2525

2626

@@ -29,44 +29,48 @@ def get(self, request):
2929
return MailingTemplateRender().render_template(request)
3030

3131

32-
def template_fields(request, schema_id):
33-
return JsonResponse(
34-
dict(MailingTemplateRender().get_template_fields_context(schema_id))
35-
)
32+
class TemplateFieldsView(APIView):
33+
def get(self, request, schema_id):
34+
return JsonResponse(
35+
dict(MailingTemplateRender().get_template_fields_context(schema_id))
36+
)
3637

3738

3839
class MailingTemplateRender:
3940
template_name = "templates/mailing/mail_schema.html"
4041

42+
@classmethod
4143
def render_template(
42-
self,
44+
cls,
4345
request,
4446
schema_id: int | None = None,
4547
picked_users: list[CustomUser] | django.db.models.QuerySet = None,
4648
unpicked_users: list[CustomUser] | django.db.models.QuerySet = None,
4749
):
4850
return render(
4951
request,
50-
self.template_name,
51-
self._get_context(
52+
cls.template_name,
53+
cls._get_context(
5254
schema_id,
5355
picked_users,
5456
unpicked_users,
5557
),
5658
)
5759

60+
@classmethod
5861
def _get_context(
59-
self,
62+
cls,
6063
schema_id: int | None = None,
6164
picked_users: list[CustomUser] | django.db.models.QuerySet = None,
6265
unpicked_users: list[CustomUser] | django.db.models.QuerySet = None,
6366
):
64-
context = self._get_schema_context(schema_id)
65-
context += self._get_users_context(picked_users, unpicked_users)
66-
context += self.get_template_fields_context(schema_id)
67+
context = cls._get_schema_context(schema_id)
68+
context += cls._get_users_context(picked_users, unpicked_users)
69+
context += cls.get_template_fields_context(schema_id)
6770
return dict(context)
6871

69-
def _get_schema_context(self, schema_id: int | None = None):
72+
@classmethod
73+
def _get_schema_context(cls, schema_id: int | None = None):
7074
all_schemas = MailingSchema.objects.all()
7175
context = {"schemas": []}
7276

@@ -77,8 +81,9 @@ def _get_schema_context(self, schema_id: int | None = None):
7781
)
7882
return list(context.items())
7983

84+
@classmethod
8085
def _get_users_context(
81-
self,
86+
cls,
8287
picked_users: list[CustomUser] | django.db.models.QuerySet = None,
8388
unpicked_users: list[CustomUser] | django.db.models.QuerySet = None,
8489
):
@@ -88,19 +93,21 @@ def _get_users_context(
8893
unpicked_users = []
8994
context = {"picked_users": [], "unpicked_users": []}
9095
for user in picked_users:
91-
context["picked_users"].append(self._user_to_dict_for_template(user, True))
96+
context["picked_users"].append(cls._user_to_dict_for_template(user, True))
9297
for user in unpicked_users:
93-
context["unpicked_users"].append(self._user_to_dict_for_template(user, False))
98+
context["unpicked_users"].append(cls._user_to_dict_for_template(user, False))
9499
return list(context.items())
95100

96-
def _user_to_dict_for_template(self, user, picked):
101+
@classmethod
102+
def _user_to_dict_for_template(cls, user, picked):
97103
return {
98104
"id": user.id,
99105
"picked": picked,
100106
"title": str(user),
101107
}
102108

103-
def get_template_fields_context(self, schema_id):
109+
@classmethod
110+
def get_template_fields_context(cls, schema_id):
104111
context = {"template_fields": []}
105112
if schema_id is None:
106113
return list(context.items())
Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,4 @@
1-
Some text
1+
<div>
2+
kek lol
3+
{{ user.first_name }}
4+
</div>
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
<div>Kek</div>

0 commit comments

Comments
 (0)