Search code examples
djangodjango-modelsdjango-admindjango-signals

Adding m2m fileds based on selected ones using


I'm trying to convert the country 'Latam' or 'Europe' to a list of countries and mantain that as a country.

For instance, when you select Latam in the list of countries the result in that m2m has to be: [latam, Argentina, Chile, Peru, etc.]

The Database is build that way... I know is better to split it Regions and Countries but I can't change it right now.

This is the aproach I made. I think this isn't the way to do it but maybe helps you help me.

 LATAM = [1, 4, 24]    

class PromoManagement(models.Model):
        [...]
        house_id = models.CharField(max_length=6)
        original_title = models.CharField(max_length=150, blank=True, null=True)
        country = models.ManyToManyField(Country)
        [...]

    def save(self, *args, **kwargs):
        self.original_title = get_orignal_title(self.house_id)
        super().save(*args, **kwargs)


def region_check(sender, instance, action, **kwargs):
    if action == 'post_add' or action == 'post_remove':
        for country in instance.country.all():
            if country.name == 'Latam':
                for id in LATAM:
                    instance.country.add(code)


m2m_changed.connect(region_check, sender=PromoManagement.country.through)

EDITED: Possible solution

I managed to make it work like this:

def latam_region_converter(sender, instance, action, pk_set, **kwargs):
    if action == 'post_add' and 95 in pk_set:
        # Latam id is 95
        instance.country.add(2, 62, 6, 3, 4, 45, 103, 36, 42, 104, 43, 34, 44, 7, 46, 37, 75, 35, 58, 38)

Problem is that if a user deletes one of that country manually it should remove latam.

if action == 'post_remove':
    # Then it checks if the country removed is on the list of latam. If true it deletes the id 95 from the list.

Solution

  • This is the way I solved.

        LATAM = (2, 62, 6, 3, 4, 45, 103, 36, 42, 104, 43, 34, 44, 7, 46, 37, 75, 35, 58, 38)
    
    
    def latam_region_converter(sender, instance, action, pk_set, **kwargs):
        if action == 'post_add' and 95 in pk_set:
            # Latam id is 95
            print('Adding latam countries')
            instance.country.add(2, 62, 6, 3, 4, 45, 103, 36, 42, 104, 43, 34, 44, 7, 46, 37, 75, 35, 58, 38)
    
        if action == 'post_remove' and any(item in LATAM for item in pk_set):
            print('Removing Latam')
            instance.country.remove(95)