vib
vib

Reputation: 2274

Database and class design Django

I am building a website for selling bikes in django. I have a class Bike that will contain the bikes; it looks like this :

class Bike(models.Model):
    brand = models.CharField(max_length=100)
    model = models.CharField(max_length=100)

Now I would like to add a field wheels describing the wheels of the bike, and I would like this field to contain possibly several fields like the brand, size of the wheel. I would like these details on wheels implementation to be separated from the bike's class specification; however, I expect each wheel to be associated to exactly one bike.

An idea I had was to do the following :

class Wheels(models.Model):
    description = models.CharField(max_length=100)
    size = models.DecimalField(max_digits=5,decimal_places=2)

and then to include a new field in my bike :

class Bike(models.Model):
    # previous fields
    wheels = models.ForeignKey(Wheels)

I have however some doubts about it :

1) is it the correct design ? If I do that I will end up with a wheels' database which I don't think I actually need. I just want to have flexible fields in my bike database. Basically I expect that I will have a one to one relationship between bikes and wheels.

2) If this is the correct design, then what I would like is to be able to add wheels on the fly while adding bike (never have to add wheels separately). What is the best way to do that ?

Thanks a lot for any hint / reference. I am a beginner with django...

Upvotes: 2

Views: 155

Answers (2)

user4230165
user4230165

Reputation:

  1. That design looks good to me - it's a good idea to keep individual objects in separate tables (in this case the components that make up the bike - particularly since they can be sold separately, and bikes can be customised with different parts)

  2. I think a simple preset class inherited from the Bicycle class should do the trick:

    class BicycleFrame(models.Model):
        brand = models.ForeignKey(Brand)
        model = models.CharField(max_length=100)
    
    # class BicycleWheels, BicyclePedals etc..
    
    class Bicycle(models.Model):
        frame = models.ForeignKey(BicycleFrame)
        wheels = models.ForeignKey(BicycleWheels)
        pedals = models.ForeignKey(BicyclePedals)
        # etc ...
    
    class PresetBicycle(Bicycle):
        pass
    
    class PurchaseableMixin(models.Model):
        user_id = models.ForeignKey(Customer)
        def purchase(self):
            # ... call this in the form handler to save this
            # instance of a bike in the database and maybe
            # email the customer to inform them of their purchase etc..
        class Meta:
            abstract = True
    
    class PurchasedBicycle(Bicycle, PurchaseableMixin):
        pass
    

.. then you can create a PresetBicycle in your admin area then in the view that you show to customers you could display the PresetBicycle by default and also provide a form to purchase it that is auto filled with the details for the PresetBicycle and that creates an instance of a PurchasedBicycle on submission (a JS framework like ReactJS and Backbone, or Angular might be best for the customer view).

Hope this helps!

P.S. Note that I haven't tested this approach myself - I'd suggest creating a few new branches in your Version Control (eg git) and setting up separate settings files for each one (import from a base settings file and use a separate database for each one to save having to mess around with too many migrations and obsolete tables) to test several approaches before making your final decision - it's good to figure this stuff out early on so that you don't end up making big structural changes later on.

P.P.S Also not that I've changed the brand field to be a ForeignKey, since you may later wish to filter on the brand..

Upvotes: 1

mhawke
mhawke

Reputation: 87134

I doubt that (in real life) you really will have a one-to-one relationship between bike and wheels - more than one bike model will surely use the same wheels.

Similar real life relationships exist between bike brands/models and components such as derailleurs, brakes, cranks, pedals etc.

By the way, you would not have separate databases for each component, each component would be modelled as a table within the same database.

So my advice is to go with the multiple table approach because you will eventually have the same components used on different bikes, and possibly vice versa for cases where there are optional components within the same basic bike model, e.g. same bike but different wheel sizes.

Upvotes: 2

Related Questions