Reputation: 1448
In my database I have a table with items who's titles can start with a letter or a non-letter-character. For example a number or an "@" or a "#". The model looks like this:
class Items(models.Model):
title = models.CharField(max_length=255)
body = models.TextField
In my view I would like to separate the model into two objects. One objects that contains all the item with a title starting with a letter and an other object with all the other items:
class ItemsView(TemplateView):
template_name = "index.html"
def get_context_data(self, **kwargs):
alpha_list = Items.objects.filter(title__startswith=<a letter>)
other_list = Items.objects.filter(title__startswith=<not a letter>)
context = {
"list_a": alpha_list,
"list_b": other_list
}
return context
I have been consulting the documents, stackoverflow and the holy google, but so far I have not been able to find a solution.
Any help is very much appreciated.
Upvotes: 5
Views: 1948
Reputation: 477854
You can slightly optimize the regular expression to:
# starts with an A-Za-z
Item.objects.filter(title__regex='^[A-Za-z]')
# starts not with A-Za-z
Item.objects.exclude(title__regex='^[A-Za-z]')
but a more important question is of course, what is a letter here. Here it will not match non-latin characters, such as Cyrillic, Arabic, etc. Furthermore it will not match characters with diacritics like äöüßÄÖÜ
, etc. You can add extra characters or character ranges to the character block (the [A-Za-z…]
) part to work with extra characters.
You can for example make use of Latin-1 Supplement [wiki], Latin Extended-A [wiki], Latin Extended-B [wiki] and Latin Extended Addition [wiki] as well with:
# starts with a Latin character
Item.objects.filter(title__regex='^[A-Za-z\uC0-\u024F\u1E00-\u1EFF]')
But we might want to add Arabic, Cyrillic, etc. characters as well.
Upvotes: 2
Reputation: 3920
You can use regex to filter (use regex101.com to test your regex) and exclude to find other Items not start with a letter
start with a letter:
alpha_list = Items.objects.filter(title__regex=r'^[a-zA-Z].*$')
the other cases:
other_list = Items.objects.exclude(title__regex=r'^[a-zA-Z].*$')
Explanation:
/^[a-zA-Z].*$/
^ asserts position at start of the string
a-z a single character in the range between a (index 97) and z (index 122) (case sensitive)
A-Z a single character in the range between A (index 65) and Z (index 90) (case sensitive)
.* matches any character (except for line terminators)
* Quantifier — Matches between zero and unlimited times, as many times as possible, giving back as needed
$ asserts position at the end of the string, or before the line terminator right at the end of the string (if any)
Upvotes: 8