You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django中POST请求无法获取Base64输入值,Tesseract OCR功能提交后页面无响应问题排查

Fix: Page Refreshes But No OCR Result Returns

Let's break down why your current setup isn't working and how to fix it:

The Core Problem

You're using Django's CreateView, which has a built-in POST request flow: it validates the form, creates a model instance, then redirects to a success URL. Your OCR logic inside get_context_data never gets properly executed because:

  1. When you submit the form, CreateView prioritizes its own form handling over your custom POST logic in get_context_data.
  2. Even if your code ran, the redirect after form submission would reset the context, so your text variable wouldn't persist to the rendered page.
  3. Your form input uses the name base64, but your CreateView specifies fields=['input']—this mismatch causes form validation to fail silently, making the view fall back to rendering an empty form.

Solution 1: Switch to TemplateView (If You Don't Need to Save Model Instances)

If storing the OCR input/result in your Ocr model isn't required, TemplateView is simpler and avoids the CreateView form conflicts:

# views.py
from django.views.generic import TemplateView
from django.http import HttpResponseRedirect
from django.urls import reverse
import base64
from io import BytesIO
from PIL import Image
import pytesseract

class IndexView(LoginRequiredMixin, TemplateView):
    template_name = "ocr/ocr.html"

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        # Pull OCR result from session (cleared after display to avoid stale data)
        context['text'] = self.request.session.get('ocr_text', '')
        self.request.session.pop('ocr_text', None)
        return context

    def post(self, request, *args, **kwargs):
        imgstring = request.POST.get('base64')
        text = ""
        if imgstring:
            # Process Base64 image
            imgstring = imgstring.split('base64,')[-1].strip()
            try:
                image_string = BytesIO(base64.b64decode(imgstring))
                image = Image.open(image_string)
                text = pytesseract.image_to_string(image)
                text = text.encode("ascii", "ignore").decode()
            except Exception as e:
                # Handle invalid Base64 or image errors (optional)
                text = f"Error processing image: {str(e)}"
        
        # Store result in session to persist through redirect
        request.session['ocr_text'] = text
        # Redirect to same page (follows Post/Redirect/Get best practice)
        return HttpResponseRedirect(reverse('ocr-view'))

Solution 2: Fix CreateView (If You Need to Save Model Data)

If you want to save the input to your Ocr model, adjust the view to work with CreateView's form flow:

First, update your model to include a field for the OCR result (if not already present):

# models.py
from django.db import models

class Ocr(models.Model):
    input = models.TextField()  # Stores the Base64 string
    result = models.TextField(blank=True)  # Stores OCR text
    created_at = models.DateTimeField(auto_now_add=True)

Then modify the view to handle form validation and OCR logic correctly:

# views.py
from django.views.generic.edit import CreateView
from django.urls import reverse_lazy
import base64
from io import BytesIO
from PIL import Image
import pytesseract
from .models import Ocr

class IndexView(LoginRequiredMixin, CreateView):
    model = Ocr
    template_name = "ocr/ocr.html"
    fields = ['input']
    success_url = reverse_lazy('ocr-view')

    def form_valid(self, form):
        # Override form_valid to add OCR processing before saving
        self.object = form.save(commit=False)
        imgstring = self.object.input
        imgstring = imgstring.split('base64,')[-1].strip()
        
        try:
            image_string = BytesIO(base64.b64decode(imgstring))
            image = Image.open(image_string)
            ocr_text = pytesseract.image_to_string(image)
            self.object.result = ocr_text.encode("ascii", "ignore").decode()
        except Exception as e:
            self.object.result = f"Error processing image: {str(e)}"
        
        self.object.save()
        # Store result in session for display after redirect
        self.request.session['ocr_text'] = self.object.result
        return super().form_valid(form)

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context['text'] = self.request.session.get('ocr_text', '')
        self.request.session.pop('ocr_text', None)
        return context

And update your HTML form to match the model field name (input instead of base64):

<form method="POST" action="{% url 'ocr-view'%}"> 
    {% csrf_token %} 
    <label for="base64"> Input Base64 :</label> 
    <input type="text" class="form-control" id="text" name="input" /> 
    <button type="submit" class="btn btn-primary mt-3" name="submit"> 
        <i class="fas fa-search"></i> Submit 
    </button> 
</form> 
<div class="card-body"> 
    <label> Result : </label> <br> 
    <span class="h3">{{text}}</span> 
</div>

Additional Checks

  • Ensure Tesseract OCR engine is installed on your system, and if you're on Windows, set the path in your view:
    pytesseract.pytesseract.tesseract_cmd = r'C:\Program Files\Tesseract-OCR\tesseract.exe'
    
  • Verify the Base64 input is well-formed (either with or without the data:image/xxx;base64, prefix—your code handles both cases).
  • Clean up your URLs: the second path <int:pk>/ points to IndexView, which is meant for creation, not detail viewing. Use DetailView for that route if needed.

内容的提问来源于stack exchange,提问作者HyperactiveSloth

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.30 20:34:05