Milano
Milano

Reputation: 18745

How to access attributes using through-model in Django?

I'm tring to figure out how to work with through-models in Django to be able to get attributes more comfortable. I know how to get some attributes using this models but it is not intuitive and it's tough to remember how to get them.

For example in my case:

class UserProfile(models.Model):
    user = models.OneToOneField(User, related_name='userprofile')   
    is_translator = models.BooleanField(default=False)
    languages = models.ManyToManyField(Language, through='UserProfileLanguage')

    def __unicode__(self):
        return '{} {}'.format(self.user.first_name, self.user.last_name)

    def __str__(self):
        return '{} {}'.format(self.user.first_name, self.user.last_name)


class Language(models.Model):
    shortcut = models.CharField(max_length=40)
    name = models.CharField(max_length=40)

    def __str__(self):
        return self.name

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)
    price_multiplier = models.FloatField()

def __str__(self):
    return self.get_name_display()

class UserProfileLanguage(models.Model):
    userprofile = models.ForeignKey(UserProfile)
    language = models.ForeignKey(Language)
    level = models.ForeignKey(Level)

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

So for example when I want to know whether a User knows a language A, I have to do this:

print A in user.userprofile.userprofilelanguage_set.all()

Is there a more simple way? When I try to print for example user.userprofile.languages it returns SolutionsForLanguagesApp.Language.None

Upvotes: 1

Views: 337

Answers (1)

Shang Wang
Shang Wang

Reputation: 25549

You shouldn't use in to search something, because it could be looping through everything in the queryset, which is slow. You should use exists():

if UserProfileLanuage.objects.filter(user=user, language=A).exists():
    # do something

Upvotes: 1

Related Questions