简体   繁体   中英

Django signals with ForeignKey Fields

I have created a knowledge structure that has "blocks"and each block has children to cater for different situations.

The code is:

models.py

class KBSBlock(models.Model):
    name = models.CharField(max_length=150, unique=True)
    code = models.CharField(max_length=4, blank=True)
    status=models.CharField(max_length=1, choices=Status_Choices, default='Draft')
    enter_by = models.ForeignKey(settings.AUTH_USER_MODEL,on_delete=models.PROTECT)
    tags = TaggableManager(blank=True)
    attribute1 = models.CharField(max_length=100)
    created_at = models.DateTimeField(auto_now_add=True)

def __str__(self):
    return self.name

def save(self, *args, **kwargs):
    if self.code is None or self.code == "":
        self.code = create_code4(self)
    super(KBSBlock, self).save(*args, **kwargs)

@receiver(post_save, sender=KBSBlock)
def create_block(sender, instance, created, **kwargs):
    if created:
        #create_block = BlockDetails.objects.create(block_dts=instance)
        print('Working!')

class BlockDetails(models.Model):
    block_dts = models.ForeignKey('KBSBlock', on_delete=models.CASCADE)
    code = models.CharField(max_length=2, blank=True)
    attribute1 = models.CharField(max_length=100, default='All')
    created_at = models.DateTimeField(auto_now_add=True)
    enter_by = models.ForeignKey(settings.AUTH_USER_MODEL,on_delete=models.PROTECT)
    status=models.CharField(max_length=1, choices=Status_Choices, default='Draft')

Whenever I create a block, I want to create a generic detail in BlockDetails for the block with (code='00', attribute1='All', enter_by='request.user')

It prints the 'working' bit with the 'create_block' line hashed out.

I am using PostgreSQL, Django 2.1 and Python 3.7, and cannot get it right.

Help Please

First of all thanks to @ Dani Herrera and @ Davit Tovmasyan ! Between the two of them I figured out what the problem was: Turns out I had a few things wrong.

The error was coming from the database: value too long for type character varying(1) telling me that I was trying to enter a string that was too long for the intended field. This field was the status field - It appears that even though the choices option worked perfectly in normal circumstances, the signal command wanted the short form of the choice only .

The correct code is as follows:

@receiver(post_save, sender=KBSBlock)
def create_block(sender, instance, created, **kwargs):
    if created:
        instance.blockdetails_set.create(block_dts=instance.name, code='00', enter_by=instance.enter_by, attribute1='All', status='D')

NB: the case of the modelname MUST be lowercase, even in the model class has uppercase letters

Once I corrected that - everything worked.

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