coderholic/django-cities

City QuerySet with alternative names and needed language code

vladimirmyshkovski opened this issue · 2 comments

Checklist

  • I have verified that I am using a GIS-enabled database, such as PostGIS or Spatialite.
  • I have verified that that issue exists against the master branch of django-cities.
  • I have searched for similar issues in both open and closed tickets and cannot find a duplicate.
  • I have reduced the issue to the simplest possible case.
  • I have included a failing test as a pull request. (If you are unable to do so we can still accept the issue.)

Steps to reproduce

    def get_queryset(self):

        qs = City.objects.prefetch_related('alt_names')

        if self.q:

        	qs = qs.filter(alt_names__name__istartswith=self.q, alt_names__language_code='ru')

        return qs

Realizing that I really need a query in alternative names, I did this:

    def get_queryset(self):

        qs = AlternativeName.objects.filter(language_code=self.request.LANGUAGE_CODE).all()

        if self.q:

        	qs = qs.filter(city__isnull=False, name__istartswith=self.q).all()[:10]

        return qs

But now I get alternative names with a prefix in the form of the language code.

If you save the form, I will have to receive the city of this alternative name (since the model is connected with the city).

But how do I get alternative names without a prefix in the form of a language code?

I want to get a list of cities in the language I need.

Expected behavior

<QuerySet [<City: Митарлам>, <City: Миттерзиль>, <City: Миттерзилль>, <City: Мистель-Бах>, <City: Михельдорф>

Or, in the worst case scenario:

<QuerySet [<AlternativeName: Митарлам >, <AlternativeName: Миттерзиль >, <AlternativeName: Миттерзилль >

Actual behavior

Result of first reproduce:

<QuerySet [<City: Mehtar Lām>, <City: Mittersill>, <City: Mittersill>, <City: Mistelbach>, <City: Micheldorf in Oberösterreich>, <City: Micheldorf in Oberösterreich>, <City: Millicent>, <City: Mildura>, <City: Mincivan>, <City: Mingelchaur>, <City: Mirzāpur>, <City: Mirandopólis>, <City: Miranda>, <City: Miracema>, <City: Mimoso do Sul>, <City: Myory>, <City: Minsk>, <City: Mikashevichy>, <City: Milton>, <City: Mirabel>, '...(remaining elements truncated)...']>
Result of second reproduce:

<QuerySet [<AlternativeName: Митарлам (ru)>, <AlternativeName: Миттерзиль (ru)>, <AlternativeName: Миттерзилль (ru)>, <AlternativeName: Мистель-Бах (ru)>, <AlternativeName: Михельдорф (Верхняя Австрия) (ru)>, <AlternativeName: Михельдорф (ru)>, <AlternativeName: Миллисент (ru)>, <AlternativeName: Милдьюра (ru)>, <AlternativeName: Миндживан (ru)>, <AlternativeName: Мингечаур (ru)>]>

blag commented

Your queryset is correct, but the __str__ function on the model is returning information you do not want. In your presentation layer, instead of relying on the internal __str__ function to convert the model instances to strings, use the name attribute directly.

Alternatively, you can use .values_list('name', flat=True) if you want to return just the list of names without the language code.

Closing, but please reopen if I have misunderstood the actual issue here.

Best of all, it would be to return the desired alt_names in the queryset of the City. AlternativeName filtered by get_language.

I understand how to do it to one city, but I do not understand how to do it within the query_set of cities.