Как запустить пользовательский код python при сохранении допустимой формы django в базе данных

#python #django #forms

#python #django #формы

Вопрос:

Новичок в Django здесь, следуя этому руководству, я создал простую форму, и моя форма корректно сохраняет данные в моей локальной базе данных, подключенной к Postgres. Мне было интересно, как я могу запускать функцию всякий раз, когда действительная форма сохраняется в базе данных? Код, который я хочу запустить, представляет собой простую функцию, которая написана в файле python, и она выполняет некоторую обработку последних данных, предоставленных первой формой. Я хочу, чтобы он запускался только при сохранении действительных данных формы, и мне было интересно, подходит ли мне триггер сигнала django. Не стесняйтесь обращаться за любыми дальнейшими разъяснениями. Другими словами, я хочу выполнить некоторую постобработку данных, которые присутствуют внутри базы данных, которая заполняется формой, и запускать постобработку только тогда, когда в базу данных введены действительные данные.

Вот мой код :

views.py

 from django.shortcuts import render
from django.http import HttpResponse
from .forms import auditform, ClientAuditForm
from django.db.models.signals import post_save
from . import rocode



# def auditingfun(request):
#     return HttpResponse('Auditing form works')
# # Create your views here.

def auditingfun(request):

    if request.method == 'POST':
        forminput = auditform(request.POST)
        if forminput.is_valid():

            Name = forminput.cleaned_data['Name']
            Origin = forminput.cleaned_data['Origin']
            ClientAddress = forminput.cleaned_data['ClientAddress']
            DispatchType = forminput.cleaned_data['DispatchType']
            ETA = forminput.cleaned_data['ETA']
            GSTIN = forminput.cleaned_data['GSTIN']
            # print(GSTIN,Name,Origin,Destination,MaterialType,Preference,ClientAddress,DispatchType,ETA)

    forminput = auditform(request.POST)
    return render(request, 'auditing/auditform.html', {'forminput': forminput} )
  

forms.py

 from django import forms
from .models import auditModel

class auditform(forms.Form):
    Origin = forms.CharField()
    Destination = forms.CharField()
    MaterialType = forms.CharField()
    Preference = forms.CharField()
    ClientAddress = forms.CharField(widget=forms.Textarea)
    Name = forms.CharField()
    GSTIN = forms.IntegerField()
    DispatchType = forms.ChoiceField(choices=[('Question','Inbound'),('Other','Outbound')])
    ETA = forms.CharField()


class ClientAuditForm(forms.ModelForm):

    class Meta:
            model = auditModel
            fields = ('Origin','Destination','MaterialType','GSTIN','Name','Preference','ClientAddress','DispatchType','ETA')
  

Просто для простоты представьте пользовательский код (импортированный в views.py файл как rocode.py ) Я только что добавил введенные данные и сохранил их в той же базе данных, в другом столбце.

Комментарии:

1. мог бы ответить на это, но если вы новичок .. посмотрите сигналы django

2. @bryan60 Я новичок, но я смогу посмотреть или исследовать все, что мне нужно сделать, чтобы это сделать. Итак, дайте мне то, что у вас есть 🙂

3. я имею в виду, что я скопирую и вставлю более или менее из документов django, но, конечно, почему бы и нет

4. Удается ли вашему коду в настоящее время фактически сохранить форму в базе данных? Не похоже, что он вообще делает это в коде, который вы вставили?

5. Вы пытались заставить его работать с помощью ClientAuditForm , а затем переключились на auditform в попытке заставить его работать? Было бы более полезно опубликовать ваш «рабочий» код, а затем любые попытки отдельно.

Ответ №1:

что вы хотите использовать здесь, так это сигналы. Сигнал — это некоторая функция, которая выполняется после добавления или обновления элемента в вашей базе данных. Предполагая, что ваша модель, к которой вы хотите подключиться, называется «MyModel», сделайте это:

 from django.db.models.signals import post_save
from django.dispatch import receiver
from myapp.models import MyModel


@receiver(post_save, sender=MyModel)
def my_handler(sender, instance, created, **kwargs):
    if created:
        # run your custom code HERE
  

экземпляр — это то, что было вставлено / обновлено, созданный имеет логическое значение, указывающее, было ли это обновлением или вставкой.

документы:https://docs.djangoproject.com/en/2.1/topics/signals

Комментарии:

1. Зачем вообще использовать сигнал? Сигналы предназначены для разрешения расширения / работы с поведением, которое нельзя легко переопределить (например, сторонние пакеты / внутренние компоненты django), или применяются ко многим разным местам. Кроме того, если желательна постобработка, не должно ли это быть post_save вместо этого?

2. сигналы предназначены для последующей обработки (да, должно быть post save, ошибка копирования вставки)

3. Чтобы уточнить, я думаю, что переопределение формы или модели save , вероятно, намного проще / чище.

4. целью является разделение обязанностей и понятный поддерживаемый код. метод сохранения формы предназначен для получения элемента в базе данных. постобработка (например, предварительное кэширование, обновление индекса поиска, отправка уведомлений, вызов webhook, вещи, которые являются своего рода дополнительными к фактическому сохранению) — это вариант использования signals.

5. Я понимаю, что вы имеете в виду, и я согласен с принципами! Однако можно утверждать, что signal — это очень «косвенное» место для этого большую часть времени. 1) Я подозреваю, что на самом деле он хочет предварительной обработки, то есть изменения данных перед их сохранением. 2) Но даже если он хочет последующей обработки, тогда, возможно, можно просто запустить обычную функцию после сохранения формы (чистое намерение, все еще отдельное и может перейти, скажем, в модуль кэширования / поиска / уведомления …)