Search code examples
djangopython-3.xformsmodelinline-formset

Django "NameError: name 'CarImageForm' is not defined" for self-referencing forms


I'm following this tutorial to create an object creation formset. The goal is to allow multiple images connected to a car object via Foreign object, to be uploaded in a single form.

The images use a formset that has one image per field, with as many 'add another image' fields dynamically created.

Running the server raises this error: "NameError: name 'CarImageForm' is not defined" when self-referencing the class which encloses the definition.

I've looked through the code and found a few minor corrections, but none seem to solve this.

forms.py

from django.forms import ModelForm, ImageField, CharField, TextInput

from .models import Car, Image, CustomUser

from django.contrib.auth.forms import AuthenticationForm, UserCreationForm, UserChangeForm
from django.forms.models import inlineformset_factory

from crispy_forms.helper import FormHelper
from crispy_forms.layout import Layout, Field, Fieldset, Div, HTML, ButtonHolder, Submit
from .custom_layout_object import Formset

class CarImageForm(ModelForm):

    class Meta:
        model = Image
        exclude = ()

    CarImageFormSet = inlineformset_factory(
        Car, Image, form=CarImageForm, fields=['car', 'image'], extra=1, can_delete=True
    )

class CreateCarForm(ModelForm):

    class Meta:
        model = Car
        exclude = ['seller']

    def __init__(self, *args, **kwargs):
        super(CarCreateForm, self).__init__(*args, **kwargs)
...  
            )
        )

Models.py (with irrelevant parts omitted)

class Car(models.Model):
    manufacturer = models.ForeignKey('Manufacturer', on_delete=models.SET_NULL, null=True)
    car_model = models.CharField('Model', max_length=50, null=True)
    description = models.TextField(max_length=4000)
    vin = models.CharField('VIN', max_length=17, help_text='Enter the 17 character VIN number.', blank=True, null=True)
    mileage = models.IntegerField(verbose_name='Mileage')
    date_added = models.DateTimeField(auto_now_add=True)
    engine_displacement = models.CharField(default=2.0, max_length=3, help_text="Engine displacement in Liters (E.g. 2.0, 4.2, 6.3)")
    price = models.IntegerField(default=0)

    seller = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.SET_NULL, null=True, blank=True)

    id = models.UUIDField(primary_key=True, default=uuid.uuid4,
    help_text="Unique ID for this car")
...
    drivetrain = models.CharField(
        max_length=4,
        choices = DRIVETRAIN_OPTIONS,
        blank=True,
        default='4WD',
    )

...
    transmission = models.CharField(
        max_length=4,
        choices=TRANSMISSION_OPTIONS,
        blank=True,
        default='5MT')
...
    forced_induction = models.CharField(
        max_length=4,
        choices=FORCED_INDUCTION_OPTIONS,
        default='n',
        )

    # ensures that no model year  can be set in the future. 
    model_year = models.IntegerField(validators=[MaxValueValidator(int(datetime.date.today().year) + 1)], null=True)
...

    status = models.CharField(
        max_length=1,
        choices=AVAILABILITY_STATUS,
        blank=True,
        default='a',
        help_text="Car availability",
    )

    class Meta:
        ordering = ['-date_added']
        permissions = (("can_change_availability", "Mark car as sold"),)  
...

class Manufacturer(models.Model):
    manufacturer_name = models.CharField(max_length=20)
    country_of_origin = models.CharField(max_length = 20)

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

class Image(models.Model):
    car = models.ForeignKey(Car, on_delete=models.SET_NULL, null=True)
    image = models.ImageField(upload_to=image_directory_path)


    def __str__(self):
        return str(self.car.manufacturer) + ' ' + str(self.car.car_model) + ' image'

The views aren't reached before the error is is thrown,if you need to see the file, just let me know.


Solution

  • Remove indent (one tab) in those lines:

        CarImageFormSet = inlineformset_factory(
            Car, Image, form=CarImageForm, fields=['car', 'image'], extra=1, can_delete=True
        )