Django localflavor field overwrite breaks form

205 Views Asked by At

I have the following form, which generates a Value error upon submition.

ValueError at /en/orders/create/

The view orders.views.order_create didn't return an HttpResponse object. It returned None instead.

my form:

from django import forms
from .models import Order
from localflavor.us.forms import USZipCodeField


class OrderCreateForm(forms.ModelForm):
    postal_code = USZipCodeField()

    class Meta:
        model = Order

        fields = ['first_name', 'last_name', 'email', 'address',
                  'postal_code', 'city']

my model:

class Order(models.Model):
    first_name = models.CharField(_('first name'), max_length=50)
    last_name = models.CharField(_('last name'), max_length=50)
    email = models.EmailField(_('e-mail'))
    address = models.CharField(_('address'), max_length=250)
    postal_code = models.CharField(_('postal code'), max_length=20)
    city = models.CharField(_('city'), max_length=100)
    created = models.DateTimeField(auto_now_add=True)
    updated = models.DateTimeField(auto_now=True)
    paid = models.BooleanField(default=False)

    class Meta:
        ordering = ('-created', )

    def __str__(self):
        return f'Order {self.id}'

my view:

def order_create(request):
    if request.method == 'POST':
        form = OrderCreateForm(request.POST)

        if form.is_valid():
            order.save()

            request.session['order_id'] = order.id

            # redirect for payment return
            return redirect(reverse('payment:process'))

    else:
        form = OrderCreateForm()
        return render(request,
                      'orders/order/create.html',
                      {'cart': cart, 'form': form})

Traceback:

Environment:


Request Method: POST
Request URL: http://127.0.0.1:8000/en/orders/create/

Django Version: 3.0.6
Python Version: 3.8.2
Installed Applications:
['django.contrib.admin',
 'django.contrib.auth',
 'django.contrib.contenttypes',
 'django.contrib.sessions',
 'django.contrib.messages',
 'django.contrib.staticfiles',
 'rosetta',
 'parler',
 'localflavor',
 'shop.apps.ShopConfig',
 'cart.apps.CartConfig',
 'orders.apps.OrdersConfig',
 'payment.apps.PaymentConfig',
 'coupons.apps.CouponsConfig']
Installed Middleware:
['django.middleware.security.SecurityMiddleware',
 'django.contrib.sessions.middleware.SessionMiddleware',
 'django.middleware.locale.LocaleMiddleware',
 'django.middleware.common.CommonMiddleware',
 'django.middleware.csrf.CsrfViewMiddleware',
 'django.contrib.auth.middleware.AuthenticationMiddleware',
 'django.contrib.messages.middleware.MessageMiddleware',
 'django.middleware.clickjacking.XFrameOptionsMiddleware']



Traceback (most recent call last):
  File "/home/[user]/.virtualenvs/shop/lib/python3.8/site-packages/django/core/handlers/exception.py", line 34, in inner
    response = get_response(request)
  File "/home/[user]/.virtualenvs/shop/lib/python3.8/site-packages/django/core/handlers/base.py", line 124, in _get_response
    raise ValueError(

Exception Type: ValueError at /en/orders/create/
Exception Value: The view orders.views.order_create didn't return an HttpResponse object. It returned None instead.

The process works fine, and redirects to a payment form, without this line in the form : postal_code = USZipCodeField()

I cant seem to understand what causes the error.

Expected behavior:

On valid form, redirect to payment.

On invalid form, validation error that is raised by USZipCodeField: "Enter a zip code in the format XXXXX or XXXXX-XXXX."

1

There are 1 best solutions below

0
On BEST ANSWER

I think the issue is that the code isn't rendering the form in the case that the form isn't valid. For an invalid form, the function returns None which is exactly the error message you're seeing. Maybe you're submitting an empty or invalid value? Try this modified (untested) version:

def order_create(request):
    if request.method == 'POST':
        form = OrderCreateForm(request.POST)

        if form.is_valid():
            order = form.save()

            request.session['order_id'] = order.id

            # redirect for payment return
            return redirect(reverse('payment:process'))

    else:
        form = OrderCreateForm()

    # FIXME Where does 'cart' come from?
    return render(request,
                  'orders/order/create.html',
                  {'cart': cart, 'form': form})

Does this work?

You might want to consider using the built-in CreateView to avoid boilerplate form processing code: https://docs.djangoproject.com/en/3.0/ref/class-based-views/flattened-index/#CreateView

If you haven't used class-based views, it's definitely something to look into. I find I can move a little faster using them but they do take a bit of time to learn and make the flow a little harder to follow when things don't work. Here are the full docs for the class based views: https://docs.djangoproject.com/en/3.0/topics/class-based-views/