OneToMany Relationship for more general django applications

I am trying to figure out how to generate a one-to-many relationship (ie "list of objects for one model to another") without using a foreign key for the child model. achieve this because the child must not know the parent in order to have a common attachment.

Example:

class Payment(models.Model):
    lease = models.ForeignKey('leaseapp.Lease')
    created_at = models.DateTimeField(auto_now_add=True)
    amount = models.IntegerField()

      

And my other app:

class Lease(models.Model):
    leaserholder = models.CharField(max_length=300)

      

Now I would like to have multiple payments in the rental, but without my payment model specific to my rental application, it should be used in other applications as well.

Was there a best practice here?

+3


source to share


2 answers


It looks like a general attitude. See django documentation here . Shared foreign keys and relationships sometimes cause problems in a later development process, but you can take that into account as well:

class Payment(models.Model):
    created_at = models.DateTimeField(auto_now_add=True)
    amount = models.IntegerField()

      

And in leaseapp



class Lease(models.Model):
    leaserholder = models.CharField(max_length=300)

class LeasePayment(models.Model):
    lease = models.ForeignKey(Lease)
    payment = models.OneToOneField(Payment)

      

Advantage: There is no magic and your database model is clear.

0


source


You can achieve this using GenericForeignKey

. For this you need properties content_type

, object_id

and content_object

in a payment model.

from django.db import models
from django.contrib.contenttypes.fields import GenericForeignKey
from django.contrib.contenttypes.models import ContentType


class Payment(models.Model):
    content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE)
    object_id = models.PositiveIntegerField()
    content_object = GenericForeignKey('content_type', 'object_id')
    created_at = models.DateTimeField(auto_now_add=True)
    amount = models.IntegerField()

      

Then you can create a rent like this. This will work for any model. So if you create a model Fee

you can also create payments for this



class Lease(models.Model):
    leaserholder = models.CharField(max_length=300)

lease = Lease.object.first()
Payment.objects.create(content_object=lease, amount=700)

      

Note. This requires installing django.contrib.contenttypes

, which is the default for most django applications. Check out the docs page on content views for more information

0


source







All Articles