Evgenii Legotckoi
Evgenii LegotckoiҚаз. 15, 2016, 9:50 Т.Ж.

Джанго - Оқулық 013. Джанго байланыс формасы

Сайтты дамытуды жалғастыра отырып, мен Django сайтында байланыс пішінін қосу үшін код үлгісін бөліскім келеді. Әртүрлі пішіндегі мақалалар болды, мысалы, түсініктемелер қосу үшін, бірақ біз тұтастай алғанда бүкіл процесс туралы айтып отырғандықтан, біз бұл тақырыпты да айналып өтпейміз.

Оның үстіне Wordpress сайты үшін бұл мен үшін ауыр тақырып болды. Бәріне жалқаулық кінәлі шығар, өйткені менде байланыс формасын өз бетімше сызу үшін PHP тілін түсіну ешқашан болған емес (нәтижесінде басқа плагин тартылды).

Django сайтындағы әзірлеме деректердің әртүрлі нысандарымен жиі жұмыс істейтінін және сонымен бірге пошта қызметтерімен жұмыс істеуге арналған модуль бар екенін ескерсек, онда мұндай пішінді қосу қиын емес.


Settings.py, urls.py, home/urls.py параметрлерін орнату

Біз жасайтын бірінші нәрсе - конфигурация файлын орнату, өйткені ол байланыс пішініндегі мазмұны бар электрондық пошта жіберілетін пошта жәшігіне қосылу үшін деректерді көрсетуі керек.

EMAIL_HOST = 'smtp.example.com'          # Сервер для отправки сообщений
EMAIL_HOST_USER = 'info@example.com'     # имя пользователя
EMAIL_HOST_PASSWORD = 'password123'      # пароль от ящика
EMAIL_PORT = 2525                        # порт для подключения
EMAIL_USE_TLS = True                     # использование протокола шифрования
DEFAULT_FROM_EMAIL = 'info@example.com'  # email, с которого будет отправлено письмо

Сондай-ақ осы файлда сіз байланыс формасына жауап беретін қолданбаны көрсетуіңіз керек. Менің жағдайда, бұл беттерді сирек өзгертуге жауап беретін үй қолданбасы, мысалы, байланыс пішіні бар бет. Сондай-ақ [django-bootstrap3] сайтында қолданылатын модуль (https://evileg.com/en/post/6/)

INSTALLED_APPS = [
    ...
    'home.apps.HomeConfig',
    'bootstrap3',
    ...
]

Әрине, негізгі urls.py файлы осы қолданбаға сұрау жіберілетін үлгіні көрсетеді.

urlpatterns = [
    url(r'^', include('home.urls')),
]

Үй қолданбасының url үлгісіне келетін болсақ, ол келесідей болады:

from django.conf.urls import url

from . import views

app_name = 'home'
urlpatterns = [
    ...
    url(r'^contacts/$', views.EContactsView.as_view(), name='contacts'),
    ...
]

Байланыс формасы

Байланыс пішінінде үш өріс бар:

  1. Аты – пайдаланушы өзін таныстыруы керек;
  2. электрондық пошта – пайдаланушы оған жауап беру үшін өзінің электрондық пошта мекенжайын көрсетуі керек;
  3. Хабарлама – тікелей пайдаланушы жібергісі келетін хабарлама.

Барлық өрістер міндетті болады. Бұл жағдайда электрондық поштаны енгізудің дұрыстығын тексеру пайдаланушы браузерінде жүзеге асырылады.

# -*- coding: utf-8 -*-

from django import forms


class ContactForm(forms.Form):

    name = forms.CharField(
        label="Имя",
        widget=forms.TextInput
    )

    email = forms.EmailField(
        widget=forms.EmailInput
    )

    message = forms.CharField(
        label="Сообщение",
        widget=forms.Textarea
    )

Өнімділік

Енді біз хабарламаны өңдеуге және байланыс пішіні бар бетті көрсетуге жауапты болатын көрініс жазамыз.

from django.shortcuts import render_to_response, reverse
from django.views import View
from django.core.mail import send_mail

from .forms import ContactForm
from project import settings


class EContactsView(View):
    template_name = 'home/contacts.html'

    # В случае get запроса, мы будем отправлять просто страницу с контактной формой
    def get(self, request, *args, **kwargs):
        context = {}
        context.update(csrf(request))    # Обязательно добавьте в шаблон защитный токен
        context['contact_form'] = ContactForm()

        return render_to_response(template_name=self.template_name, context=context)

    def post(self, request, *args, **kwargs):
        context = {}

        form = ContactForm(request.POST)

        # Если не выполнить проверку на правильность ввода данных,
        # то не сможем забрать эти данные из формы... хотя что здесь проверять?
        if form.is_valid():
            email_subject = 'EVILEG :: Сообщение через контактную форму '
            email_body = "С сайта отправлено новое сообщение\n\n" \
                         "Имя отправителя: %s \n" \
                         "E-mail отправителя: %s \n\n" \
                         "Сообщение: \n" \
                         "%s " % \
                         (form.cleaned_data['name'], form.cleaned_data['email'], form.cleaned_data['message'])

            # и отправляем сообщение
            send_mail(email_subject, email_body, settings.EMAIL_HOST_USER, ['target_email@example.com'], fail_silently=False)

        return render_to_response(template_name=self.template_name, context=context)

Бұл жерде беттің пайдаланушыға қалай көрсетілетініне қатысты бір маңызды мәселе бар. Егер пайдаланушы хат жіберген болса, оған хат жіберілгені туралы хабарлау қажет. Мұны істеу үшін біз жай ғана контекстке байланыс пішінін орналастырмаймыз және пайдаланушыға дұрыс ақпаратты көрсету үшін үлгіде оның бар-жоғын тексереміз.

Байланыс пішінінің үлгісі

Байланыс пішінінде сайтыңызды контакт пішіні арқылы шабуылдардан қорғайтын {% csrf_token %} көрсетуіңіз керек. Сондай-ақ, дұрыс және әдемі бет көрінісін жасауға мүмкіндік беретін bootsrtap3 модулін жүктеуді ұмытпаңыз.

bootstrap3 модулімен байланыс пішінін пайдалану үшін сізге сәйкес үлгі тегін көрсетіңіз және оған біздің байланыс пішінін жіберсеңіз жеткілікті. Сондай-ақ, сіздердің назарларыңызды байланыс формасының қолжетімділігіне қарай беттің басқа көрінісі көрсетілетініне аударамын.

{% extends 'home/base.html' %}{% load bootstrap3 %}
{% block title %}Контакты{% endblock %}
{% block page %}
    <h1>Контакты</h1>
    <article>
    {% if contact_form %}
        <p>Добро пожаловать на сайт.</p>
        <p>Если у Вас есть пожелания или предложения по улучшению сайта, либо Вы желаете предложить статью к публикации на сайте, то Вы можете сделать это, воспользовавшись контактной формой:</p>
        <form id="contact_form" action="{% url 'home:contacts' %}" method="post">
            {% csrf_token %}
            {% bootstrap_form contact_form %}
            {% buttons %}
                <button type="submit" class="btn btn-primary">{% bootstrap_icon "send" %}&nbsp;&nbsp;Отправить</button>
            {% endbuttons %}
        </form>
    {% else %}
        <p>Сообщение отправлено</p>
    {% endif %}
    </article>
{% endblock %}

Django үшін Timeweb хостының VDS сервері ұсынамын.

Байланыс пішінінің коды forms.py файлында орналасады.

Рекомендуем хостинг TIMEWEB
Рекомендуем хостинг TIMEWEB
Стабильный хостинг, на котором располагается социальная сеть EVILEG. Для проектов на Django рекомендуем VDS хостинг.

Ол саған ұнайды ма? Әлеуметтік желілерде бөлісіңіз!

DR
  • Мамыр 31, 2019, 11:12 Т.Ж.
  • (өңделген)

Не полноценное решение, сильно вырвано из контекста.

B
  • Жел. 26, 2019, 1:08 Т.Ж.

Здавствуйте! обязательно ли форма в django должна быть привязана к модели? конкретно в этом случаи

Evgenii Legotckoi
  • Қаң. 6, 2020, 3:16 Т.Ж.

Добрый день. Конкретно в этом случае модель не привязана к форме вообще потому, что здесь модель не используется. Вы можете использовать модель, чтобы дополнительно сохранять сообщения в базе данных сайта.

S
  • Мамыр 17, 2020, 6:37 Т.Ж.

Добрый день,
не могу отправить загруженный файл, подскажите что нужно еще добавить.
Спасибо.

forms:
class ContactForm(forms.Form):

    name = forms.CharField(
        label="Имя",
        widget=forms.TextInput
    )

    email = forms.EmailField(
        widget=forms.EmailInput
    )

    message = forms.CharField(
        label="Сообщение", required=False,
        widget=forms.Textarea
    )
    file = forms.FileField(
        label="Загрузить файл", required=False,
    )

views:
class EContactsView(View):
    template_name = 'main/contacts.html'

    # В случае get запроса, мы будем отправлять просто страницу с контактной формой
    def get(self, request, *args, **kwargs):
        context = {}
        context['contact_form'] = ContactForm()
        return render(request, template_name=self.template_name, context=context)

    def post(self, request, *args, **kwargs):
        context = {}

        form = ContactForm(request.POST, request.FILES)

        # Если не выполнить проверку на правильность ввода данных,
        # то не сможем забрать эти данные из формы... хотя что здесь проверять?
        if form.is_valid():

            email_subject = ':: Сообщение через контактную форму '
            email_body = "С сайта отправлено новое сообщение\n\n" \
                         "Имя отправителя: %s \n" \
                         "E-mail отправителя: %s \n\n" \
                         "Сообщение: \n" \
                         "%s " % \
                         (form.cleaned_data['name'], form.cleaned_data['email'], form.cleaned_data['message'], form.cleaned_data['file'])


            # и отправляем сообщение

            send_mail(email_subject, email_body, settings.EMAIL_HOST_USER, ['mymail@gmail.com'], fail_silently=False)

        return render(request, template_name=self.template_name, context=context)

шаблон:

{% extends "layout/basic.html" %}
{% load thumbnail %}
{% load static %}
{% load bootstrap4 %}
{% block title %}Контакты{% endblock %}

{% block content %}
    <h1>Контакты</h1>
    <article>
    {% if contact_form %}
        <p>Добро пожаловать на сайт.</p>
        <p>Если у Вас есть пожелания или предложения по улучшению сайта, либо Вы желаете предложить статью к публикации на сайте, то Вы можете сделать это, воспользовавшись контактной формой:</p>
        <form id="contact_form" action="{% url 'main:contacts' %}" method="post" enctype="multipart/form-data">
            {% csrf_token %}
            {% bootstrap_form contact_form %}

            {% buttons %}
                <button type="submit" class="btn btn-success">&nbsp;&nbsp;Отправить</button>
            {% endbuttons %}
        </form>
    {% else %}
        <p>Сообщение отправлено</p>
    {% endif %}
    </article>
{% endblock %}
Evgenii Legotckoi
  • Мамыр 18, 2020, 3:20 Т.Ж.

Добрый день.
Потому, что нужно не добавлять ссылку (или что там у вас в итоге получается) на файл и прикреплять его к письму.
Если не ошибаюсь, то для отправки письма с файлом нужно использовать класс EmailMessage

def send_email(request):
    ...
    email = EmailMessage(
        subject,
        content,
        contact_email,
        [to],
        headers={'Reply-To': contact_email}
    )
    if request.FILES:
        uploaded_file = request.FILES['file'] # file is the name value which you have provided in form for file field
        email.attach(uploaded_file.name, uploaded_file.read(), uploaded_file.content_type)
    email.send()

Могут быть некоторые разночтения в синтаксисе, в зависимости от версий Django

S
  • Мамыр 20, 2020, 7:08 Т.Ж.

Добрый день, в итоге получилось как-то так, отправляет форму с файлом.
Спасибо.

settings:

EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'

views:

from django.core.mail import EmailMessage
from django.conf import settings

def contacts(request):
    if request.method == 'POST':
        form = ContactForm(request.POST)
        if form.is_valid():
            email_subject = ' Сообщение через контактную форму '
            email_body = "С сайта отправлено новое сообщение\n\n" \
                         "Имя отправителя: %s \n" \
                         "E-mail отправителя: %s \n\n" \
                         "Сообщение: \n" \
                         "%s " % \
                         (form.cleaned_data['name'], form.cleaned_data['email'], form.cleaned_data['message'])

    email = EmailMessage(
        email_subject,
        email_body,
        settings.EMAIL_HOST_USER,
        ['mymail@gmail.com'],
    )
    if request.FILES:
        uploaded_file = request.FILES['file'] # file is the name value which you have provided in form for file field
        email.attach(uploaded_file.name, uploaded_file.read(), uploaded_file.content_type)
    email.fail_silently=False

    email.send()
    return render(request, 'main/contacts.html')
S
  • Мамыр 22, 2020, 7:52 Т.Ж.

Добрый день,
при отправки письма с файлом, выбираю несколько файлов, пишет выбранное количество файлов, а отправляет только один, весь код см.выше, добавил только в форму возможность выбора нескольких файлов. Подскажите,что нужно еще добавить, чтобы можно было отправить сразу несколько файлов.
Спасибо.

class ContactForm(forms.Form):
file = forms.FileField(
        label="Загрузить файл", required=False,
        widget = forms.FileInput(attrs={'multiple': True})

    )
Evgenii Legotckoi
  • Мамыр 22, 2020, 7:57 Т.Ж.

Думаю, что как-то так, возможно неправильно написание имени метода getlist, но выглядеть должно так

if request.FILES:
    for f in request.FILES.getlist('file'):
        email.attach(f.name, f.read(), f.content_type)
S
  • Мамыр 22, 2020, 11:10 Т.Ж.

Спасибо, Евгений.
Все заработало.

def contacts(request):
    if request.method == 'POST':
        form = ContactForm(request.POST)
        if form.is_valid():
            email_subject = ' Сообщение через контактную форму '
            email_body = "С сайта отправлено новое сообщение\n\n" \
                         "Имя отправителя: %s \n" \
                         "E-mail отправителя: %s \n\n" \
                         "Сообщение: \n" \
                         "%s " % \
                         (form.cleaned_data['name'], form.cleaned_data['email'], form.cleaned_data['message'])

        email = EmailMessage(
            email_subject,
            email_body,
            settings.EMAIL_HOST_USER,
            ['mymail@gmail.com'],
            )
        if request.FILES:
            for f in request.FILES.getlist('file'):
                email.attach(f.name, f.read(), f.content_type)
        email.fail_silently=False
        email.send()
    return render(request, 'main/contacts.html')
d
  • Ақп. 16, 2023, 11:15 Т.Ж.

Timeweb так себе провайдер.
Поддержка не отвечает. И smtp не отправляет письма.
Все перепробовал ничего найти не могу.
1. Ошибка sock.connect(sa) TimeoutError: [Errno 110] Connection timed out
2. Ошибка OSError: [Errno 101] Network is unreachable

Пікірлер

Тек рұқсаты бар пайдаланушылар ғана пікір қалдыра алады.
Кіріңіз немесе Тіркеліңіз
AD

C++ - Тест 004. Указатели, Массивы и Циклы

  • Нәтиже:50ұпай,
  • Бағалау ұпайлары-4
m
  • molni99
  • Қаз. 26, 2024, 1:37 Т.Ж.

C++ - Тест 004. Указатели, Массивы и Циклы

  • Нәтиже:80ұпай,
  • Бағалау ұпайлары4
m
  • molni99
  • Қаз. 26, 2024, 1:29 Т.Ж.

C++ - Тест 004. Указатели, Массивы и Циклы

  • Нәтиже:20ұпай,
  • Бағалау ұпайлары-10
Соңғы пікірлер
i
innorwallҚар. 11, 2024, 10:12 Т.Қ.
Django - Оқулық 055. Автоматты толтыру өрісі функциясын қалай жазу керек Freckles because of several brand names retin a, atralin buy generic priligy
i
innorwallҚар. 11, 2024, 6:23 Т.Қ.
QML - Сабақ 035. C++ қолданбай QML тілінде сандарды пайдалану priligy cvs 24 Together with antibiotics such as amphotericin B 10, griseofulvin 11 and streptomycin 12, chloramphenicol 9 is in the World Health Organisation s List of Essential Medici…
i
innorwallҚар. 11, 2024, 3:50 Т.Қ.
Qt/C++ - 052-сабақ. Qt аудио ойнатқышын AIMP стилінде теңшеу It decreases stress, supports hormone balance, and regulates and increases blood flow to the reproductive organs buy priligy online safe Promising data were reported in a PDX model re…
i
innorwallҚар. 11, 2024, 2:19 Т.Қ.
Үйінді сұрыптау алгоритмі The role of raloxifene in preventing breast cancer priligy precio
i
innorwallҚар. 11, 2024, 1:55 Т.Қ.
PyQt5 - Оқулық 006. QTableWidget-пен жұмыс buy priligy 60 mg 53 have been reported by Javanovic Santa et al
Енді форумда талқылаңыз
i
innorwallҚар. 11, 2024, 8:56 Т.Қ.
добавить qlineseries в функции buy priligy senior brother Chu He, whom he had known for many years
i
innorwallҚар. 11, 2024, 10:55 Т.Ж.
Всё ещё разбираюсь с кешем. priligy walgreens levitra dulcolax carbs The third ring was found to be made up of ultra relativistic electrons, which are also present in both the outer and inner rings
9
9AnonimҚаз. 25, 2024, 9:10 Т.Ж.
Машина тьюринга // Начальное состояние 0 0, ,<,1 // Переход в состояние 1 при пустом символе 0,0,>,0 // Остаемся в состоянии 0, двигаясь вправо при встрече 0 0,1,>…

Бізді әлеуметтік желілерде бақылаңыз