Milano
Milano

Reputation: 18745

How to set hierarchy on Django objects of the same class?

I'm working on a web for translators in Django. Each translator can speak different languages on different levels. So translator 1 can speak English on level 'professional', translator 2 can speak English on level 'native'.

There are four different Levels. (Level is a model)

class Level(models.Model):
    LEVEL_CHOICES = (
        ('unknown', _('Unknown')),
        ('standard', _('Standard level')),
        ('professional', _('Professional level')),
        ('native', _('Native speaker level')),
    )

    name = models.CharField(max_length=40, choices=LEVEL_CHOICES, blank=False, null=False,
                            help_text=_('Choose a level'))

    def __str__(self):
        return '{}'.format(self.get_name_display())

And model LanguageLevel:

class LanguageLevel(models.Model):
    language = models.ForeignKey(Language,
                                 help_text=_('Choose a language'), related_name='language_levels')
    level = models.ForeignKey(Level,
                              help_text=_('Choose a level of the language'))
    price_multiplier = models.FloatField(default=0.0,
                                         help_text=_('Type a price multiplier'))

    def __str__(self):
        return '{}: {}'.format(self.language, self.level)

    class Meta:
        unique_together = (('level', 'language'),)

Now what's the problem. The problem is that if I want to get, for example, translator speaking English on level 'standard', in fact, I want to get translators speaking English on level either 'standard', 'professional' or 'native' because those, who can speak 'native' can speak 'standard' too.

There are many situations in my project like this so I would like to simplify this.

So unknown<standard<professional<native. Now if I try to get all translator speaking English on standard level, I want to get professional and native too.

Could you give me advice?

Upvotes: 0

Views: 46

Answers (1)

H&#229;ken Lid
H&#229;ken Lid

Reputation: 23064

You can use an integerfield instead of charfield. This makes querying on level simple.

LEVEL_CHOICES = (
    (0, _('Unknown')),
    (1, _('Standard level')),
    (2, _('Professional level')),
    (3, _('Native speaker level')),
)

level = models.IntegerField(choices=LEVEL_CHOICES, default=0,
                        help_text=_('Choose a level'))

I'm not sure why you need the Level model. I would have just put everything into LanguageLevel.

Your query would look something like this:

LanguageLevel.objects.filter(level__gte=1, language__name='English')

Upvotes: 2

Related Questions