A design using events can help you to track actions of your users. In the code bellow, you have 3 classes dedicated to your stuff here (Bike, Glove, Helmet), and an Event class which will be instantiated every time a user borrow stuff or render stuff.
With all this data in your database, you are able to know the state of your stuff (borrowed or available) in real time plus have an history of everything.
You can add fields like "lender" to your stuff classes, but it's not DRY and can create inconsistency. On the other hand, it can help you to NOT create impossible events (like borrowing already borrowed stuff).
class Bike(models.Model):
lender = models.ForeignKeyField(User)
# lender == None means your Bike is available!
class Glove(models.Model)
lender = models.ForeignKeyField(User)
class Helmet(models.Model)
lender = models.ForeignKeyField(User)
class BorrowOrRenderEvent(models.Model):
date = models.DateTimeField(auto_now_add=True)
# Stuff borrowed or rendered (we assume we can't borrow AND render stuff in the same event)
bike = models.ForeignKeyField(Bike)
gloves = models.ManyToManyField(GloveEquipment)
helmets = models.ManyToManyField(HelmetEquipment)
# Who is performing this action?
user = models.ForeignKey(User)
# We need to know if the event is about borrowing or rendering stuff
is_rendering = models.BooleanField()
How to know how many equipment someone currently got?
In a class that extends the User class, add a method like this:
def count_borrowed_equipment_per_user(self):
nb_bikes = Bike.objects.filter(lender=self.user).count()
nb_helmets = Helmet.objects.filter(lender=self.user).count()
nb_gloves = Glove.objects.filter(lender=self.user).count()
return nb_bikes, nb_helmets, nb_gloves
Note
I'd like to tell that in my opinion, in general and in that case, database only cannot ensure functional consistency. It's easy to insert crap in DB even with good designing, if your business logic is bad :)