I am writing a method in views.py that should return a list of Artist objects by country and genre.

I have this code in models.py:

GENRES = ((1, 'Alternative'),
          (2, 'Blues'),
          (3, 'Classical'),
          (4, 'Country'),
          (5, 'Disco'),
          (6, 'Drum and Bass'),
          (7, 'Dubstep'),
          (8, 'EDM'),
          (9, 'Electronic'),
          (10, 'Experimental'),
          (11, 'Folk'),
          (12, 'Funk'),
          (13, 'Garage'),
          (14, 'Grime'),
          (15, 'Hardstyle'),
          (16, 'Heavy Metal'),
          (17, 'Hip Hop'),
          (18, 'House'),
          (19, 'Indie'),
          (20, 'Jazz'),
          (21, 'Multi-Genre'),
          (22, 'Pop'),
          (23, 'Punk'),
          (24, 'R&B'),
          (25, 'Reggae'),
          (26, 'Rock'),
          (27, 'Ska'),
          (28, 'Soul'),
          (29, 'Techno'),
          (30, 'Trance'),
          (31, 'Urban'),
          (32, 'World'))

genres = MultiSelectField(choices=GENRES, null=True)
country = CountryField(default="Poland")

Currently I am looping through all objects and search the ones I need using python:

countries_selection = request.POST.get('countriesSelection')
genres_selection = request.POST.get('genresSelection')

results = []

artists = Artist.objects.all()
for artist in artists:
    if artist.country.name == countries_selection:
        if artist.genres:
            for genre in artist.genres.__str__().split(","):
                if genres_selection in genre:

Obviously this is not a good approach. I want to get the same results by using query. I tried:

Artist.objects.filter(genres__contains = 'Rock')

But it does not return anything because only keys are saved in the database, not values. For example this query work, but I will not have the key in my views.py function:

Artist.objects.filter(genres__contains = '26')

1 Answers

Jay On Best Solutions

That's not a bad approach; it's essentially the best way to configure what you are trying to do, if you assist on using a multi-select field. Otherwise, I would suggest using a manytomany field in this type of instance. Allows for much easier referencing. (FYI: Multiselect just saves ('25', 'genre') as a comma separated string. That's why your method is best in this case)