MaxFields
MaxFields

Reputation: 23

Getting values from queryset in Django

Facing troubles with getting values from foreign key models. I have one model, where included all foreign key relations.

class UserAccount(models.Model):
    name= models.CharField(max_length=100)
    surname = models.CharField(max_length=100)
    category= models.ManyToManyField(Category)
    account = models.ForeignKey(Account)
    country = models.ForeignKey(Country)
    permissions = models.ForeignKey(Permissions)


class Country(models.Model):
    iso_code = models.CharField(max_length=6)
    zip_code = models.CharField(max_length=10)

I'm using this to get all fields related to model UserAccount:

user_account_data = UserAccount.objects.all()
name = user_account_data.values_list('name', flat=True)))
surname = user_account_data.values_list('surname', flat=True)))

But when trying this, its giving me: 'QuerySet' object has no attribute 'country'

countries = user_account_data.country.values('iso_code')

Upvotes: 1

Views: 4458

Answers (2)

willeM_ Van Onsem
willeM_ Van Onsem

Reputation: 476624

Please do not make use of .values(…) [Django-doc] or .values_list(…) [Django-doc]: first of all you will here make one query for each value so if you evaluate name, surname, and countries, then you make three queries. Furthermore it is not even said that these queries will produce results in the same order, so matching the items will be a second problem, and finally this will produce dictionaries/lists of values: these thus "erode" the model layer, and introduce a primitive obsession antipattern [refactoring.guru].

Usually one works with model objects, you can thus fetch all the data for the UserAccount with the corresponding Country data with:

for item in UserAccount.objects.select_related('country'):
    print(item.name)
    print(item.surname)
    print(item.country.iso_code)

You can thus use these in a template, in a serializer, form, etc. It guarantees that the .name, .surname and .country.iso_code are of the same item. item.country is a Country object: so you can pass this to functions that work with a Country object (for example serialize, update, etc.). It is thus more convenient to work with model objects, than with dictionaries/lists/… that contain data of these objects.

Upvotes: 1

rahul.m
rahul.m

Reputation: 5854

try this

countries = user_account_data.values('country__iso_code')

https://docs.djangoproject.com/en/4.0/ref/models/querysets/#django.db.models.query.QuerySet.values

Upvotes: 4

Related Questions