I want to create a symmetric relationship on my model and also add a field in the relationship. I came across this blog (and also this another blog) and followed the steps in creating my own models.
class CreditCardIssuer(models.Model):
name = models.CharField(_('name'), max_length=256)
transfer_limits = models.ManyToManyField('self', through='Balancetransfer', related_name='no_transfer_allowed+', symmetrical=False, help_text=_('List of issuers to which balance transfer is not allowed.'))
def add_balancetransfer(self, creditcardissuer, until):
balance_transfer, _newly_created = Balancetransfer.objects.get_or_create(
no_transfer_from=self,
no_transfer_to=creditcardissuer,
until=until)
balance_transfer, _newly_created = Balancetransfer.objects.get_or_create(
no_transfer_from=creditcardissuer,
no_transfer_to=self,
until=until)
return balance_transfer
def remove_balancetransfer(self, creditcardissuer, until):
Balancetransfer.objects.filter(
no_transfer_from=self,
no_transfer_to=creditcardissuer,
until=until).delete()
Balancetransfer.objects.filter(
no_transfer_from=self,
no_transfer_to=creditcardissuer,
until=until).delete()
return
def get_transfer_limits(self, until):
return self.transfer_limits.filter(
no_transfer_to__until=until,
no_transfer_to__no_transfer_from=self)
class Balancetransfer(models.Model):
no_transfer_from = models.ForeignKey('CreditCardIssuer', related_name='no_transfer_from')
no_transfer_to = models.ForeignKey('CreditCardIssuer', related_name='no_transfer_to')
until = models.IntegerField(blank=True, null=True, help_text='Minimum card ownership period to allow balance transfer.')
class Meta:
unique_together = ('no_transfer_from', 'no_transfer_to')
But when I create the relationship from admin, only one is created. Can you please help me figure out the problem?
You say you've got one half of this in the Django admin (you don't say how, but I'll assume it works unless you post the code): the remaining step is to set up the half of the relationship that's missing.
I suspect that if you put a breakpoint in your add_balancetransfer()
method (import pdb; pdb.set_trace()
), you'll find that it is never being called — the part of the relation that is created is done through built-in Django admin behaviour.
In short, you might just need to call add_balancetransfer()
yourself when the model is saved — or, better yet, a different version that only adds the missing relationship.
One way to do this is overriding the model's save()
method, but this can be a little fragile. For your situation, it may work better to fill in the missing relationship in the model's post_save
signal:
from django.db.models.signals import post_save
from django.dispatch import receiver
from yourapp.models import CreditCardIssuer
@receiver(post_save, sender=CreditCardIssuer)
def add_missing_relationship(sender, **kwargs):
# Add the other side of what should be a symmetrical relationship
...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With