简体   繁体   中英

building models with foreignkey and OnetoOne relationship in Django?

I am trying to make models for my project.

1) This includes a model for CarInfo , which holds details about the car, such as year, make and model.

class CarInfo(models.Model):
    year = models.IntegerField(blank=True, null=True)
    make=models.OneToOneField('Manufacturer')

2) for the car make, I am thinking of the following model;

class Manufacturer(models.Model):
    CARMAKER_CHOICES=(('Toyota','TOYOTA'),
                    ('ford','FORD'),
                    ('mazda','MAZDA'), ('Honda','HONDA'), )
    carmaker=models.CharField(max_length=20,choices=CARMAKER_CHOICES)

3) for the car model, I want to make the following model, but I do not know how to implement it.

class CarModel(models.Model):
    maker=models.ForeignKey(Manufacturer)
    # if the manufacturerer is Toyota, the different models are
    MODEL_CHOICES=(('Prius','PRIUS'),
                    ('Camry','CAMRY'),
                    ('Rav4','RAV4'),)
    carmodel=models.CharField(max_length=20,choices=MODEL_CHOICES)

As you can see the CarModel is dependent on the manufacturer and hence car model choices will be entirely different. How should I build a model in this case or I am open to better alternative models.

Django alone cannot conditionally display/use choices based on another. Probably the easiest approach would be to use Javascript/jQuery on your page to display the choices based on previous selection.

Alternatively, you could also look at using Django's form wizard to show the form at multiple stages.

Either way, this will have to be done at the form/template level and not in the model itself.

UPDATE

There's no way to dynamically populate fields/attributes based on another field in the current model. Additionally, the car models that correspond to their manufacturers will have to be stored somewhere. Currently in MODEL_CHOICES , but as you've explained you want this to be populated based on the manufacturer plus it might become a hassle to keep updating tuples going forward so it's best put in the database.

So if we changed the CarModel and CarInfo models slightly,

class CarModel(models.Model):
    carmaker = models.ForeignKey(Manufacturer)
    carmodel = models.CharField(max_length=20)

class CarInfo(models.Model):
    year = models.IntegerField(blank=True, null=True)
    make = models.OneToOneField('Manufacturer')
    model = models.CharField(max_length=20)

it could hold that information for us like so:

+-----+------------+------------+
| id  |  carmaker  |  carmodel  |
+-----+------------+------------+
|  1  |   Toyota   |   Prius    |
|  2  |   Toyota   |   Camry    |
...

Then if we ever need to filter/restrict the models to their manufacturers via CarInfo , say in a form, it can be done so with a simple query:

class CarInfoForm(forms.ModelForm):
    class Meta:
        model = CarInfo

    def __init__(self, *args, **kwargs):
        super(CarInfoForm, self).__init__(*args, **kwargs)
        self.fields['model'] = forms.ModelChoiceField(queryset=CarModel.objects.filter(carmodel=self.instance.carmodel))

Again, this would be much simpler to do via Javascript or jQuery in the template/browser. If you are not opposed to using third-party libraries there are some that add functionality around models as choice fields: dj-choices , django-smart-select and this django snippet were a few I found.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM