Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/278.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 使用Django保存前处理字段输入_Python_Django - Fatal编程技术网

Python 使用Django保存前处理字段输入

Python 使用Django保存前处理字段输入,python,django,Python,Django,我目前正在使用Django构建一个web应用程序,我已经实现了一个可能被称为“签名字段”的功能。本质上,它使用jQueryUIpluginat实现签名捕获字段,当表单提交时,通过AJAX POST将其作为Base64编码字符串发送到服务器,然后在服务器上转换为图像 现在,我已经将它的客户端方面重构为一个可重用的小部件,称为SignatureInput,并且我还在一个单独的视图中实现了它的服务器端方面。然而,我真的很想让它成为通用字段,这样我就可以在现有的通用视图中使用它,而这正是我正在努力的地方

我目前正在使用Django构建一个web应用程序,我已经实现了一个可能被称为“签名字段”的功能。本质上,它使用jQueryUIpluginat实现签名捕获字段,当表单提交时,通过AJAX POST将其作为Base64编码字符串发送到服务器,然后在服务器上转换为图像

现在,我已经将它的客户端方面重构为一个可重用的小部件,称为SignatureInput,并且我还在一个单独的视图中实现了它的服务器端方面。然而,我真的很想让它成为通用字段,这样我就可以在现有的通用视图中使用它,而这正是我正在努力的地方——它可能只是暂时的一棵树,但我在Django文档中找不到任何涉及这种情况的内容

SignatureField本身扩展了ImageField,在管理界面中,我想继续使用现有的图像上传对话框,所以我不想在模型级别覆盖它。相反,当它仅在前端提交时,我希望它从request.POST中提取、处理并添加到request.FILES中

我在widgets.py中为它定义了以下小部件:

class SignatureInput(ClearableFileInput):
def render(self, name, value, attrs=None):
    try:
        id = self.attrs['id']
    except KeyError:
        id = None
    if id: 
        id_html = ' id="%s"' % (id)
    else:
        id_html = ''

    # Value is set - show existing image and field to change it
    if value:
        html = """ 
    <div class="signatureContainer">
    <br /><img class="existingSignature" alt="Signature" title="Signature" src="/media/%s"></img>
    <div data-role="collapsible">
        <h4>New signature</h4>
        <br /><div class="signature"%s></div><br /><br />
        <a data-role="button" class="signatureClear">Clear signature</a>
    </div>

        """ % (value, id_html)
    else:
        html = """
    <div class="signatureContainer">
    <br /><div class="signature"%s></div><br /><br />
    <a data-role="button" class="signatureClear">Clear signature</a>
    </div>
        """ % (id_html)
    return html

在提交过程的早期,我如何执行addJob view函数中当前完成的处理,以便将签名字段与通用视图一起使用?基本上,我需要能够将字符串处理成图像,并在它进入视图之前将其从request.POST移动到request.FILES。中间件似乎不是这样做的地方。

您可以尝试在自定义小部件中使用
value\u from\u datadict
方法来执行此操作。从该函数的Django docstring:

给定数据字典和此小部件的名称,返回值 这个小部件的名称。如果未提供,则返回None

这个方法应该返回一个基于POST数据字典和小部件名称的值。因此,在您的情况下,您可以从POST中读取base64字符串并将其转换为图像文件数据。此数据需要与ImageField所期望的内容相对应

这个问题使用了我提到的函数:

还可以在此处检查此函数的Django代码:

小部件只处理字段的html repr。您应该重写jobform
save()
方法(或者,特别是
您的_save()
one)@SamueleMattiuzzo jobform在本例中是一个ModelForm。这是否意味着这样做的方式是覆盖特定字段的默认save()方法,而不是表单或模型(在这种情况下,我特别不想在模型中这样做,因为它仍然需要在管理中以常规方式工作)我说的是jobform,而不是与之关联的模型:)您可以覆盖表单“
save()
method或仅字段
save()
method,由您决定。你就是不能在晚上做这件事widget@SamueleMattiuzzo好的,在我脑子里澄清一下。干杯,我想这已经足够让我走了,我很高兴它成功了。由于您的问题,我了解了此方法,因此谢谢:)
# Create your views here.
import cStringIO as StringIO
from xhtml2pdf import pisa
from django.http import HttpResponse, HttpResponseRedirect
from django.template.loader import get_template
from django.template.context import Context
from django.shortcuts import render, render_to_response
from my_app.models import *
from my_app.forms import JobForm
from django.core.files.uploadedfile import InMemoryUploadedFile
from django.conf import settings
import base64
import uuid
import sys 


def decodeImage(image):
    # Remove encoding data
    image = image.replace('data:image/png;base64,', '') 

    # Decode image
    image = base64.b64decode(image)

    # Return it
    return image


def addJob(request):
    # If request is a GET request, just render it
    if request.method == 'GET':
        return render_to_response('my_app/job_form.html', {'form': JobForm})
    elif request.method == 'POST':
        # If request is a POST request, process it
        # Get the signatures
        if request.POST.get(u'signature'):
            signature = StringIO.StringIO(decodeImage(request.POST[u'signature']))

            # Construct the File objects
            signatureOutput = InMemoryUploadedFile(signature,
                    field_name='signature',
                    name=settings.MEDIA_ROOT + str(int(uuid.uuid1()))[:10] + '.png',
                    content_type="image/png",
                    size=sys.getsizeof(signature),
                    charset=None)
            request.FILES[u'signature'] = signatureOutput

        # Validate the data
        jobform = JobForm(request.POST, request.FILES)

        if jobform.is_valid():
            # Save the form as a new instance of Job
            jobform.save()

            # Show the success page
            return HttpResponseRedirect('/forms/jobs/add/success/')
        else:
            # Return an error
            return render(request, 'my_app/job_form.html', {
                'form': jobform,
            })