add contact_us app

remotes/origin/HEAD
Max Yakovenko 8 years ago
parent 9800358b25
commit a181c54093
  1. 1
      contact_us/__init__.py
  2. 0
      contact_us/admin.py
  3. 7
      contact_us/apps.py
  4. 5
      contact_us/context_processors.py
  5. 85
      contact_us/forms.py
  6. 58
      contact_us/mixins.py
  7. 69
      contact_us/models.py
  8. 0
      contact_us/templatetags/__init__.py
  9. 8
      contact_us/templatetags/custom_admin_modify.py
  10. 22
      contact_us/tests.py
  11. 7
      contact_us/urls.py
  12. 62
      contact_us/views.py

@ -0,0 +1 @@
default_app_config = 'contact_us.apps.ContactUsConfig'

@ -0,0 +1,7 @@
from django.apps import AppConfig
from django.utils.translation import ugettext_lazy as _
class ContactUsConfig(AppConfig):
name = 'contact_us'
verbose_name = _("Contact requests")

@ -0,0 +1,5 @@
from contact_us.forms import ContactUsForm
def contact_us_form(request):
return {'contact_us_form': ContactUsForm()}

@ -0,0 +1,85 @@
from crispy_forms.helper import FormHelper
from crispy_forms.layout import Layout, Div, HTML, Field, Submit
from django import forms
from django.conf import settings
from django.urls import reverse_lazy
from django.utils.translation import ugettext_lazy as _
from ckeditor.widgets import CKEditorWidget
from .mixins import RequestNotifiable
from .models import (
Request,
STATUS_NEW, STATUS_REJECTED,
STATUS_PROCESSED, STATUS_IN_PROCESSING
)
# -------------------------------- Client-side forms -----------------------------------#
class ContactUsForm(RequestNotifiable, forms.ModelForm):
field_template = 'bootstrap/forms/product_search.html'
def __init__(self, *args, **kwargs):
self.helper = FormHelper()
self.helper.form_action = reverse_lazy('contact_us:send')
self.helper.form_method = 'post'
self.helper.layout = Layout(
HTML("""
<div class="left-menu__title">
Не нашли нужную программу или разработчика?
Заполните форму и с Вами свяжется наш специалист.
</div>"""),
Field('name', css_class="left-menu__text", placeholder=_("Имя"), template=self.field_template),
Field('email', css_class="left-menu__text", placeholder=_("Email"), template=self.field_template),
Field('subject', css_class="left-menu__text", placeholder=_("Название продукта"), template=self.field_template),
Field('phone', css_class="left-menu__text", placeholder=_("Номер телефона"), template=self.field_template),
Submit('send', _("Отправить"), css_class="left-menu__btn")
)
super(ContactUsForm, self).__init__(*args, **kwargs)
self.init_fields(self.fields)
def init_fields(self, fields):
for field_name in fields:
fields[field_name].required = True
def save(self, commit=True):
self.instance.status = STATUS_NEW
return super().save(commit)
def send_email(self, request, files=()):
context = {
'from_email': self.instance.type.author.email,
'bcc': self.get_def_email(settings) if self.get_def_email(settings) is not None else (),
'recipients': self.instance.type.author.email,
'context': {
'username': self.instance.name,
'email': self.instance.email,
'subject': self.instance.subject,
'message': self.instance.message,
'sent_at': self.instance.create_at,
'attachments': files,
'edit_link': request.scheme + "://" + request.get_host() + reverse_lazy(
'admin:{}_{}_change'.format(
self.instance._meta.app_label,
self.instance._meta.object_name.lower()),
args=(self.instance.id,)
).__str__(),
},
'files': [],
'send_at_date': self.instance.create_at,
}
self.send_request_notification(
context,
)
@property
def is_request_sent(self):
return self.notification_sent
class Meta:
model = Request
fields = ('name', 'email', 'subject', 'phone')

@ -0,0 +1,58 @@
from django.template.loader import get_template
from django.utils.translation import ugettext_lazy as _
class RequestNotifiable(object):
MAIL_CATEGORY = 'Request'
SLUG_NOTIFICATION = 'notification'
SLUG_RESPONSE = 'response'
def __init__(self, *args, **kwargs):
super(RequestNotifiable, self).__init__(*args, **kwargs)
def get_mail_template(self, **kwargs):
return None
# return MailTemplate.objects.filter(**kwargs).first()
def send_request_notification(self, context):
"""
:param context
:param template_path string:
:return None:
"""
notification = self.get_mail_template(
slug=self.SLUG_NOTIFICATION,
)
kwargs = {
'subject': _('New contact us request'),
'message': get_template('contact_us/contact_email_notification.html').template.source,
}
if not notification:
kwargs.update({
'name': 'Admin notification',
'slug': self.SLUG_NOTIFICATION,
'num_of_retries': 3,
'is_html': True
})
# MailTemplate.objects.create(**kwargs)
else:
notification.subject = kwargs.get('subject')
notification.message = kwargs.get('message')
notification.save()
# send_db_mail(
# self.SLUG_NOTIFICATION,
# context.get('recipients'),
# context.get('subject'),
# context.get('context'),
# from_email=context.get('from_email', tuple()),
# bcc=context.get('bcc', tuple()),
# files=context.get('files', tuple()),
# send_at_date=context.get('send_at_date'),
# retry=True,
# retry_delay=300,
# max_retries=3,
# use_celery=celery_supported()
# )

@ -0,0 +1,69 @@
import os
from django.conf import settings
from django.contrib.auth import get_user_model
from django.core.validators import RegexValidator
from django.db import models
from django.utils.translation import ugettext_lazy as _
# Create your models here.
from core.models import AbstractStatusModel, STATUS_DELETED
# --------------------- REQUEST STATUS LIST --------------------
STATUS_NEW = 0
from core.models import AbstractStatusModel, STATUS_NEW, STATUS_CHOICES, STATUS_ACTIVE, STATUS_DELETED
# --------------------- REQUEST STATUS LIST --------------------
STATUS_IN_PROCESSING = 10
STATUS_PROCESSED = 20
STATUS_REJECTED = 40
REQUEST_STATUS_CHOICES = (
STATUS_CHOICES[0],
(STATUS_IN_PROCESSING, _('Processing')),
(STATUS_PROCESSED, _('Processed')),
(STATUS_REJECTED, _('Rejected')),
STATUS_CHOICES[-1]
)
REQUEST_DEFAULT_STATUS = STATUS_NEW
# ----------------- REQUEST FILE STATUS LIST ------------------
FILE_REQUEST_STATUS_CHOICES = (
(STATUS_ACTIVE, _('Active')),
(STATUS_DELETED, _('Deleted')),
)
FILE_REQUEST_DEFAULT_STATUS = STATUS_ACTIVE
class Request(AbstractStatusModel):
name = models.CharField(_('Name'), max_length=255)
email = models.EmailField(_('Email'))
subject = models.CharField(_('Subject'), max_length=500)
message = models.TextField(blank=True, null=True)
phone_regex = RegexValidator(regex=r'^\((+7)|8)?\d{10}$',
message="Phone number must be entered in the format: '+99999999999'. Up to 12 digits allowed.")
phone = models.CharField(validators=[phone_regex], max_length=12, blank=True, null=True)
status = models.SmallIntegerField(_('Status'), default=REQUEST_DEFAULT_STATUS, choices=REQUEST_STATUS_CHOICES)
@property
def is_status_processed(self):
return self.status == STATUS_PROCESSED
@property
def is_status_rejected(self):
return self.status == STATUS_REJECTED
@property
def is_status_processing(self):
return self.status == STATUS_IN_PROCESSING
def __str__(self):
return self.subject
class Meta:
verbose_name = _('Request')
verbose_name_plural = _('Requests')

@ -0,0 +1,8 @@
from django.contrib.admin.templatetags.admin_modify import submit_row, register
@register.inclusion_tag('admin/contact_us/custom_submit_line.html', takes_context=True)
def custom_submit_row(context):
ctx = submit_row(context)
ctx['show_answer'] = context.get('show_answer',True)
return ctx

@ -0,0 +1,22 @@
from django.test import TestCase
from core.tests import BehaviourTestCaseMixin
from .models import Request
# Create your tests here.
class SendRequestWithTestCase(BehaviourTestCaseMixin, TestCase):
model = Request
def create_instance(self, **kwargs):
return self.get_model()
def send_form_without_attachments_by_db_mailer(self):
pass
def send_form_with_attachments_by_db_mailer(self):
pass
def save_attachments_locally(self):
pass

@ -0,0 +1,7 @@
from django.conf.urls import url
from .views import ContactUsFormView
urlpatterns = [
url(r'^send/$', ContactUsFormView.as_view(), name='send'),
]

@ -0,0 +1,62 @@
import logging
from django.contrib import messages
from django.contrib.messages.views import SuccessMessageMixin
from django.db import transaction
from django.urls import reverse_lazy
from django.views.generic import FormView
from django.utils.translation import ugettext_lazy as _
from .forms import ContactUsForm
logger = logging.getLogger(__name__)
# Create your views here.
class ContactUsFormView(SuccessMessageMixin, FormView):
template_name = None
form_class = ContactUsForm
http_method_names = ['post']
success_message = _('Request has been sent successfully!')
error_message = _('Some errors occurred during sending the request. Check the input fields or try latter.')
def get_initial(self):
initial = super().get_initial()
if self.request.method == "GET":
initial['type'] = RequestType.objects.order_by('order').first()
if self.request.user.is_authenticated():
initial['name'] = self.request.user.profile.get_full_name(self.request, self.request.user.profile)
initial['email'] = self.request.user.email
return initial
def form_valid(self, form):
try:
with transaction.atomic():
if self.request.user.is_authenticated():
form.instance.user = self.request.user
form.save()
files = []
if len(self.request.FILES) > 0:
attachments = AttachmentFormSet(self.request.POST, self.request.FILES, form_kwargs={'request': form.instance})
if attachments.is_valid():
attachments.save()
files = attachments.get_file_absolute_urls(self.request)
form.send_email(self.request, files)
return super().form_valid(form)
except ValueError as ve:
logger.critical(ve)
messages.error(self.request, self.error_message, 'danger')
except Exception as e:
logger.critical(e)
messages.error(self.request, self.error_message, 'danger')
return self.form_invalid(form)
def form_invalid(self, form):
context = self.get_context_data()
if len(form.errors) > 0:
context['form_show_errors'] = True
return self.render_to_response(context)
def get_success_url(self):
return super().get_success_url()
Loading…
Cancel
Save