防止在Django发布双重(或更多)帖子

时间:2015-12-08 22:54:39

标签: python django session post

我正在使用django构建的网站,但是我遇到了一些麻烦,在多个部分我得到双倍(有时3或4)帖子,例如我提交一个表格,你需要保存联系人,但当页面重新加载即可获得相同联系人的2,3或4个。时间差约为0.5秒。彼此。

我尝试编写一个像这样的小解决方案:

def not_double_post(request):
    session_data = request.session.get('post_data', None)
    session_new_data = '-'.join([str(request.user.username),
                                 str(int(time.time()))])
    if session_data is None:
        request.session['post_data'] = session_new_data
        return True
    else:
        current_user = request.user.username
        current_time = int(time.time())
        session_post_user = session_data.split('-')[0]
        session_post_time = session_data.split('-')[1]
        if current_user == session_post_user:
            time_difference = current_time - int(session_post_time)
            if time_difference > 10:
                request.session.pop('post_data')
                request.session['post_data'] = ''.join([str(current_user),
                                                     str(int(time.time()))])
                return True
            else:
                return False
        else:
            return True

在每个request.method =='POST'我检查这个功能,存储用户和操作在会话中的时间,如果操作用户是相同的,并且时间差小于10秒,是一篇无效的帖子。

(我还在用户点击时将按钮的属性设置为禁用)

但我得到双重帖子。我不知道这是否真的像我期望的那样,但是采取另一种观点(或另一种推荐来实现这一目标)会很好。

谢谢!

==== UDATE views.py =====

def cancel_invoice(request, pk):
if not_double_post(request):
    order = PaymentOrder.objects.get(pk=pk)
    order.cancelled_date = datetime.date.today()
    folio = order.invoice_sat.comp_folio
    serie = order.invoice_sat.comp_serie
    rfc_receptor = order.client.rfc
    folio = folio
    soap_doc = '<soapenv:Envelope ' \
               'xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" ' \
               'xmlns:xsaf="http://xsafilereceiver.webservices.manager.xsa.tralix.com">' \
               '<soapenv:Header/>' \
               '<soapenv:Body>' \
               '<xsaf:cancelaCFD>' \
               '<xsaf:in0>' + serie + '</xsaf:in0>' \
               '<xsaf:in1>' + folio + '</xsaf:in1>' \
               '<xsaf:in2>' + settings.IENTC_RFC + '</xsaf:in2>' \
               '<xsaf:in3>' + settings.API_KEY + '</xsaf:in3>' \
               '</xsaf:cancelaCFD>' \
               '</soapenv:Body>' \
               '</soapenv:Envelope>'

    factura_client = ServiceClient(settings.API_CANCEL_URL)
    invoice_status = factura_client.service.cancelaCFD(__inject={'msg': soap_doc})
    if invoice_status:
        order.invoice_sat.invoice_status = 0
        order.amount_to_pay = None
        order.invoice_sat.save()
        order.save()
        if serie == settings.INVOICE_SERIE:
            order.client.balance = order.client.balance + order.total
        else:
            order.client.balance = order.client.balance - order.total
        order.client.save()
        comment = request.POST.get('comment', None)
        if comment.strip() != '' and comment is not None:
            cancelled_folio = folio
            CANCEL_EVENT = 'Administración'
            CANCEL_INVOICE_TITLE = 'Cancelación de Factura #%s' % \
                                   str(cancelled_folio)
            cancel_type, created = EventType.objects.get_or_create(
                name=CANCEL_EVENT)
            Event(
                client=order.client,
                register_date=datetime.datetime.now(),
                event_type=cancel_type,
                event=CANCEL_INVOICE_TITLE,
                additional_comments=comment.strip(),
                created_by=request.user
            ).save()
            mandrill_client = mandrill.Mandrill(settings.MADRILL_API_KEY)
            message = dict()
            message['subject'] = 'Cancelación de Factura'
            message['from_email'] = 'crm@ientc.com'
            message['from_name'] = 'CRM IENTC'
            message['text'] = CANCEL_INVOICE_TITLE
            message['to'] = [
                {
                    'email': 'conta@ientc.com',
                    'name': 'Contabilidad IENTC',
                    'type': 'to'
                }
            ]
            result = mandrill_client.messages.send(
                message=message, async=False)
            print result
        return response_json("OK", 200)
    else:
        return response_json("ERROR CANCELANDO FACTURA", 400)
else:
    return response_json("OK", 200)

在这个特别的POST中,我正在拨打肥皂电话,但我在其他POST上遇到麻烦,只需要简单的代码。谢谢!

0 个答案:

没有答案