Django Model.Objects.order_by charField which can contain notes written in different languages(ENG, RUS) - django

I have a model:
class A(models.Model):
name = models.CharField(max_length=120)
name can be written in two languages: English and Russian. When i use A.objects.order_by('-name'), English words stand before Russian. How can i swap it?

This was asked almost three years ago, but if you would like to swap the order, you could simply do:
query = A.objects.order_by("name")
Django changes the order by ascending and descending based on the presence of a - symbol before the field name.

Related

Filter multiple Django model fields with variable number of arguments

I'm implementing search functionality with an option of looking for a record by matching multiple tables and multiple fields in these tables.
Say I want to find a Customer by his/her first or last name, or by ID of placed Order which is stored in different model than Customer.
The easy scenario which I already implemented is that a user only types single word into search field, I then use Django Q to query Order model using direct field reference or related_query_name reference like:
result = Order.objects.filter(
Q(customer__first_name__icontains=user_input)
|Q(customer__last_name__icontains=user_input)
|Q(order_id__icontains=user_input)
).distinct()
Piece of a cake, no problems at all.
But what if user wants to narrow the search and types multiple words into search field.
Example: user has typed Bruce and got a whole lot of records back as a result of search.
Now he/she wants to be more specific and adds customer's last name to search.So the search becomes Bruce Wayne, after splitting this into separate parts I'm having Bruce and Wayne. Obviously I don't want to search Orders model because order_id is a single-word instance and it's sufficient to find customer at once so for this case I'm dropping it out of query at all.
Now I'm trying to match customer by both first AND last name, I also want to handle the scenario where the order of provided data is random, to properly handle Bruce Wayne and Wayne Bruce, meaning I still have customers full name but the position of first and last name aren't fixed.
And this is the question I'm looking answer for: how to build query that will search multiple fields of model not knowing which of search words belongs to which table.
I'm guessing the solution is trivial and there's for sure an elegant way to create such a dynamic query, but I can't think of a way how.
You can dynamically OR a variable number of Q objects together to achieve your desired search. The approach below makes it trivial to add or remove fields you want to include in the search.
from functools import reduce
from operator import or_
fields = (
'customer__first_name__icontains',
'customer__last_name__icontains',
'order_id__icontains'
)
parts = []
terms = ["Bruce", "Wayne"] # produce this from your search input field
for term in terms:
for field in fields:
parts.append(Q(**{field: term}))
query = reduce(or_, parts)
result = Order.objects.filter(query).distinct()
The use of reduce combines the Q objects by ORing them together. Credit to that part of the answer goes to this answer.
The solution I came up with is rather complex, but it works exactly the way I wanted to handle this problem:
search_keys = user_input.split()
if len(search_keys) > 1:
first_name_set = set()
last_name_set = set()
for key in search_keys:
first_name_set.add(Q(customer__first_name__icontains=key))
last_name_set.add(Q(customer__last_name__icontains=key))
query = reduce(and_, [reduce(or_, first_name_set), reduce(or_, last_name_set)])
else:
search_fields = [
Q(customer__first_name__icontains=user_input),
Q(customer__last_name__icontains=user_input),
Q(order_id__icontains=user_input),
]
query = reduce(or_, search_fields)
result = Order.objects.filter(query).distinct()

What is the difference between SlugField() vs CharField() in Django models

So, in my Django projects, I made my model to be like the following
class Store(models.Model):
domainKey = models.CharField()
I had the above to make each store has its own domain like the following
www.domain.com/my-name-is-django
Anyway, it was perfectly working fine. But, I just found out SlugField() which is used for the same purpose as what I did in above.
My question is why we need to use SlugField() because I implemented the same thing without SlugField(). Is there its own any feature that CharField() doesn't have?
A slug is a string without special characters, in lowercase letters and with dashes instead of spaces, optimal to be used in URLs. An example of slug could be:
example/this-is-a-slug/150
you can look for more information here Documentation django slug
CharField has max_length of 255 characters , and accept special characters.
About CharField Here

What's 'slug' for in Django? [duplicate]

This question already has answers here:
What is a "slug" in Django?
(13 answers)
Closed 5 years ago.
In Django generic views, there's slug_field, and slug_url_kwarg.
In this context, what is the definition of slug?
I choose the more persuasive explanation within items of 3 dictionaries.
In Cambridge dictionary:
A piece of metal used instead of a coin for putting in machines
In MW:
A disk for insertion in a slot machine; especially :one used illegally instead of a coin
In Oxford:
A part of a URL which identifies a particular page on a website in a form readable by users.
They don't seem to make sense.
It is from the publishing world from wikipedia:
In newspaper editing, a slug is a short name given to an article that
is in production. The story is labeled with its slug as it makes its
way from the reporter through the editorial process. The AP Stylebook
prescribes its use by wire reporters (in a "keyword slugline") as
follows: "The keyword or slug (sometimes more than one word) clearly
indicates the content of the story."[1] Sometimes a slug also contains
code information that tells editors specific information about the
story — for example, the letters "AM" at the beginning of a slug on a
wire story tell editors that the story is meant for morning papers,
while the letters "CX" indicate that the story is a correction to an
earlier story.[2][3] In the production process of print
advertisements, a slug or slug line, refers to the "name" of a
particular advertisement. Advertisements usually have several markers,
ad numbers or job numbers and slug lines. Usually the slug references
the offer or headline and is used to differentiate between different
ad runs.
From there, the slug for web publishing was born as an effort to make more semantic URLs. This is the slug as used in django:
Some systems define a slug as the part of a URL that identifies a page
in human-readable keywords.[4][5] It is usually the end part of the
URL, which can be interpreted as the name of the resource, similar to
the basename in a filename or the title of a page. The name is based
on the use of the word slug in the news media to indicate a short name
given to an article for internal use. Slugs are typically generated
automatically from a page title but can also be entered or altered
manually, so that while the page title remains designed for display
and human readability, its slug may be optimized for brevity or for
consumption by search engines. Long page titles may also be truncated
to keep the final URL to a reasonable length. Slugs are generally
entirely lowercase, with accented characters replaced by letters from
the English alphabet and whitespace characters replaced by a dash or
an underscore to avoid being encoded. Punctuation marks are generally
removed, and some also remove short, common words such as
conjunctions. For example:
Original title: This, That and the Other! An Outré Collection
Generated slug: this-that-other-outre-collection
Django provides a slug field, and in its documentation provides a definition as well:
Slug is a newspaper term. A slug is a short label for something,
containing only letters, numbers, underscores or hyphens. They’re
generally used in URLs.

Django countries order by translated name

I started using django_countries and added a field to one of my models
country = CountryField(blank=True)
The problem is the users language is spanish and when the form shows the list of countries they are correctly translated, but they ordered by the code I guess, or by the English name.
I want it to be ordered by the display name so the users can easily search any country by typing the first letter and then going down until the find it (the way most of people does).
Any ideas?
Thank uou for your time
This was the solution, based on this
function sort(a, b) {
return (a.innerHTML > b.innerHTML) ? 1 : -1;
};
$('#select_id option').sort(sort).appendTo('#select_id');
If you want to do it server side, you can do something like this:
things = sorted(things, key=lambda thing:Country(thing['country']).name)
That's what I used.

Django Order_by blank

I have a simple model
title = models.CharField(max_length=250)
url = models.CharField(max_length=250)
title_french = models.CharField(max_length=250)
I want to order it via title_french, however when it orders in A-Z in this way, all the blank values are at the top. In the case ot blank values I display the English title.
So I get A-Z for the French titles, but at the top there is a load of English title unordered.
Any advice?
For your case, I think you should do the sorting in your python code (currently, as it is, the sorting is made in the database). It is not possible, imho, to do what you want in the db, at least without writing some sql by hand.
So the idea would be to do something like this in your view :
your_objects = list(YourObject.objects.filter(....))
your_objects.sort(key=lambda ob: ob.title_french if ob.title_french else ob.title)
As long as you sort small lists, this should not be a too problematic performance issue.
have you tried ordering by multiple fields (doc):
ordering = ('title_french', 'title')
specify both the columns, title_french and title in order_by
queryset.order_by('title_french', 'title')
title_french will be given first preference and if there are two entries with the same title_french then those two entries will be sorted by their title
Here is a way to order blank value last while only using the ORM:
from django.db.models import Case, When, Value
...
title_french_blank_last = Case(
When(title_french="", then=Value(1)),
default=Value(0)
)
...
queryset.order_by(title_french_blank_last, "title_french", "title")
Django has the option to order nulls_first and nulls_last, for details see the docs.
In your case it would be something like this (not tested):
MyModel.objects.order_by(Coalesce('title_french', 'title').asc(nulls_last=True))
You would still have to do some logic in Python to display the title when the french title is None.