使用as_crispy_field渲染Django表单时持续报错:as_crispy_field got passed an invalid or inexistent field
Fixing "as_crispy_field got passed an invalid or inexistent field" in Django
Let's break down why you're hitting this error and walk through the fixes step by step:
Root Causes of the Error
- Incorrect form initialization for GET requests: You're creating a form bound to
request.POSTeven when handling GET requests (which have empty POST data). This confuses crispy forms about the state of your fields. - Uninitialized foreign key fields: Your
companyandsenderfields aren't getting default values, so crispy forms struggles to render them correctly. - Missing file upload support: Your form handles a
FileFieldbut doesn't include the required enctype attribute, which will cause upload failures later (even if it's not the immediate error).
Step 1: Fix the View Logic
Update your send_email view to properly initialize the form for GET requests, set default values for foreign key fields, and handle file uploads in POST:
from django.contrib import messages from django.shortcuts import get_object_or_404, render def send_email(request, id): customer = get_object_or_404(Customer, pk=id) customers = Customer.objects.all() if request.method == 'GET': # Initialize an unbound form with default values for foreign keys initial_data = { 'company': customer, # Auto-set to the selected customer 'sender': request.user # Auto-set to the logged-in user } form = Customer_Email_Form(initial=initial_data) context = {"customer": customer, "email_form": form, "customers": customers} return render(request, 'crm/email_form.html', context) # Handle POST requests (including file uploads) if request.method == 'POST': form = Customer_Email_Form(request.POST, request.FILES) if form.is_valid(): # Save without committing to DB first to set values explicitly email_instance = form.save(commit=False) email_instance.sender = request.user email_instance.company = customer email_instance.save() messages.success(request, "Email Sent") return render(request, 'crm/listing.html', context) # If form is invalid, return it with errors context = {"customer": customer, "email_form": form, "customers": customers} return render(request, 'crm/email_form.html', context)
Step 2: Update the HTML Template
Add the required enctype for file uploads, and convert your company and sender fields to hidden inputs (since users shouldn't need to edit them):
{% load crispy_forms_tags %} <!-- Add enctype to support file uploads --> <form class="" method="POST" enctype="multipart/form-data"> {% csrf_token %} <div class="form-group m-2"> <label>Subject</label> {{ email_form.subject|as_crispy_field }} </div> <div class="form-group m-2"> <label>Message</label> {{ email_form.message|as_crispy_field }} </div> <div class="form-group m-2"> <label>Upload</label> {{ email_form.file_upload|as_crispy_field }} <span class="color-secondary">you can attach 2M files (pdf,doc)</span> </div> <!-- Hide foreign key fields since they're auto-populated --> {{ email_form.company.as_hidden }} {{ email_form.sender.as_hidden }} <button class="btn btn-primary btn-lg mt-5" type="submit" hx-post="email_form/p={{customer.id}}" hx-target="#crm-list" data-dismiss="modal" > Send Email <i class='bx bx-mail-send bx-xl'></i> </button> </form>
Step 3: Verify Crispy Forms Setup
Double-check your settings.py to ensure crispy forms is properly configured (this is a common overlooked step):
INSTALLED_APPS = [ # ... your other apps 'crispy_forms', 'crispy_bootstrap5', # Use bootstrap4 if you're on an older Bootstrap version ] # Set the template pack matching your project's Bootstrap version CRISPY_TEMPLATE_PACK = 'bootstrap5'
Why This Works
- Unbound form for GET: Creating an unbound form (without
request.POST) ensures crispy forms recognizes all fields correctly when rendering the empty form. - Hidden foreign keys: By hiding
companyandsender, you avoid rendering issues while still passing their values to the backend. - File upload support: The
enctype="multipart/form-data"attribute lets Django process the uploaded file correctly.
内容的提问来源于stack exchange,提问作者Ahmad Hashim
相关产品推荐
相关产品推荐

