1

I am creating an application where users can set objects and the corresponding data they want to record. Let me give you an example:

class vehicle_type(models.Model):
    name = models.CharField(max_length=20, unique=True)
    int1_name = models.CharField(max_length=20, blank=True, null=True)
    int1_default = models.IntegerField(blank=True, null=True)
    int2_name = models.CharField(max_length=20, blank=True, null=True)
    int2_default = models.IntegerField(blank=True, null=True)
    float1_name = models.CharField(max_length=20, blank=True, null=True)
    float1_default = models.FloatField(blank=True, null=True)

class vehicle(models.Model):
    registration = models.CharField(max_length=20)
    vehicle_type = models.ForeignKey(vehicle_type)
    int1_val = models.IntegerField(blank=True, null=True)
    int2_val = models.IntegerField(blank=True, null=True)
    float1_val = models.FloatField(blank=True, null=True)

Where the data would be something like this to describe the vehicles:

    # pseudo code
    vehicle_type('Car','Seats',4,'Doors',4,'',)
    vehicle_type('Van','Seats',2,'',,'Load',3.2)

and then the data on the vehicles would be:

    vehicle('ABC 123',1,2,2,) #sports car
    vehicle('DEF 456',1,6,,) #SUV
    vehicle('GHI 789',2,,,1.2) #light van
    vehicle('JKL 246',2,4,3,3.6) #heavy van

My question is how can I make sure that the vehicleForm does not display the fields NOT required by the vehicle_type? I know I could pass an instance of the vehicle_type to the vehicleForm template and only display elements of the vehicleForm if they are declared in the vehicle_type, but this seems unnecessary and moves logic into the template. (I hope all this makes sense)

Robert Johnstone
  • 5,431
  • 12
  • 58
  • 88

1 Answers1

1

You can pass vehicle_type to VehicleForm.__init__(), and put there some custom logic which would, for example, set widgets of fields that are not required to HiddenInput.

Basic example (code is not tested)::

class VehicleForm(forms.ModelForm):
    def __init__(self, vehicle_type, *args, **kwargs):
        if vehicle_type.name == 'Car':
            self.fields[some_field_for_trucks].widget = forms.HiddenInput()
        super(VehicleForm, self).__init__(*args, **kwargs)

And when you instantiate VehicleForm in you view, you just pass as a first argument your the vehicle_type selected by user.

See examples of dynamic forms:

Community
  • 1
  • 1
Anton Strogonoff
  • 32,294
  • 8
  • 53
  • 61
  • Thanks! I didn't think to look up `dynamic forms`. I'm afraid `car` is a dynamic variable. I think more then lightly in my situation you'd pass the the key for `vehicle_type` and then test to see if the variable has a name, if it doesn't then you'd hide the input. PS(thanks for the links, I'm reading them at the moment) – Robert Johnstone Jun 08 '11 at 13:33