django json field: which one? - django

I am looking for a JSON field for Django.
I have found mainly 2 jsonfield app and I am not sure which one I should use.
The main difference I see is that the first one does not have the native JSON datatype support for PostgreSQL anymore.
It has been removed recently (https://github.com/bradjasper/django-jsonfield/commit/15957c9dab18c546ae5c119f8a6057e5db6b2135). It was related to this issue https://github.com/bradjasper/django-jsonfield/issues/57
but I am not sure if it's the right approach since JSONB is also coming soon with PostgreSQL 9.4. I think it's better to use the native datatype when using PostgreSQL. What do you think?
1) https://github.com/bradjasper/django-jsonfield
2) https://bitbucket.org/schinckel/django-jsonfield/

Since Django 1.9 JSON support is back again with JSONField:
https://docs.djangoproject.com/en/1.9/ref/contrib/postgres/fields/

Related

Django - How to store emojis in postgres DB properly?

I'm running the latest version of Django on postgres. I'm trying to store emojis in my postgres DB in a way that a React Native app can properly render it. Below I have the initial emojis variables setup that'll go into the table. I've copy and pasted the emojis from here. How do I store emojis in my postgres DB so that a React Native app can render it properly?
I tried following this blog, which suggests adding ’OPTIONS’: {’charset’: ’utf8mb4’} to DATABASES under settings.py, but I get this error django.db.utils.ProgrammingError: invalid dsn: invalid connection option "charset". Seems like this only works for MySQL DBs. How can I store emojis in a Django postgres DB?
Like in the comments suggested, you need to put quotes around the emojis since they're just chars. Though, something like flags is actually two chars. So that's something to be careful about. All your computer is doing is converting unicode to a rendered emoji that's platform dependent.
The emojis that you're using should be unicode supported. On your computer, they're definitely supported. For the most part, additional unicode support for new emojis is very quickly implemented once published on client machines. There should be no problem with emojis in strings. This is a nice video kinda explaining emojis by Tom Scott who keeps getting interviews about emojis: https://www.youtube.com/watch?v=sTzp76JXsoY
I'm not an expert so please correct me if I'm wrong.
In your models you need to use a CharField or a TextField to store emojis, that need to be passed as characters (for example "😄" and not directly 😄). Your database must use utf8 to support emojis, connect to your database with a SQL shell, to check the current encoding run:
SHOW CLIENT_ENCODING;
If the output is not UTF8 run:
SET CLIENT_ENCODING='UTF8';
Now remove ’OPTIONS’: {’charset’: ’utf8mb4’} from your Django settings.

How do I query the length of a Django ArrayField?

I have an ArrayField in a model, I'm trying to annotate the length of this field ( so far without any luck)
F('field_name__len') won't work since join is not allowed inside F(). Even
ModelName.objets.values('field_name__len') is not working
Any idea?
I'm using django 1.11
The extra() function has been deprecated according to the docs:
Use this method as a last resort
This is an old API that we aim to deprecate at some point in the future. Use it only if you cannot express your query using other queryset methods.
Here is how you can do the same thing using a custom Annotation function:
from django.db import models
class ArrayLength(models.Func):
function = 'CARDINALITY'
MyModel.objects.all().annotate(field_len=ArrayLength('field')).order_by('field_len')
Note that the cardinality() function is available in PostgreSQL 9.4 or later. If you're using an older version, you have to use array_length():
MyModel.objects.all().annotate(field_len=Func(F('field'), 1, function='array_length')).order_by('field_len')
One caveat with this second query is that an empty array will be sorted in front of all non-empty ones. This could be solved by coalescing NULL values from array_length to 0.
ModelName.objects.extra(select={'length':'cardinality(field_name)'}).order_by('length')
you can try this
Tested on django 3.5, your query now works!
I'm not sure which version added this offhand, but give it a try, or try upgrading if you can.
ModelName.objects.values('field_name__len')
<ModelName [{'field_name__len': 1}]>
Also some other things to try:
ModelName.objects.filter(field_name__len__gt=0)
ModelName.objects.filter(field_name__len__gte=0)
ModelName.objects.filter(field_name__len=0)
ModelName.objects.filter(field_name__len__lte=10)
ModelName.objects.filter(field_name__len__lt=10)

Accent insensitive search django sqlite

I am using sqlite and django. I am trying to search for accented strings stored in the sqlite database using non-accented search query.
For example: search for "Rio Grande" when the database contains "Río Grande".
I found this SO post SQLite accent-insensitive search that mentions to first create a collation and then call the search query using COLLATE NOACCENTS
This is exactly what I need. However I am not sure how to do this using django models. Any suggestions?
As suggested in this Postgres specific post on django documentation: PostgreSQL specific lookups I tried the following:
myObject.objects.filter(locationTuple__unaccent__contains='Rio Grande')
but got the following error:
FieldError: Unsupported lookup 'unaccent' for CharField or join on the field not permitted. which is understandable because this lookup might not work for sqlite.
I think this is the closest thing you're going to find, however, it needs some development work:
https://github.com/djcoin/django-unaccent
I'm jealous as well, as my workplace isn't on PostgreSQL either (yet).

How to use Django 1.4 with Xeround?

According to Xeround's Release Notes they don't support save points and I can't figure out how to turn off support for this in Django 1.4. Does anyone know how to accomplish this?
I had the same problem. Django seems to only check the version of the MySql when it decides whether to use savepoints or not. Xeround probably uses some non-standard database-engine that doesn't support savepoints even if the MySql version is high enough.
Quick fix (just for testing) is to just edit the django/db/backends/mysql/base.py to override the logic:
Before:
self.features.uses_savepoints = self.get_server_version() >= (5, 0, 3)
After:
self.features.uses_savepoints = False
I tested this and it didn't seem to cause problems.
Note: Editing django sources directly like this is not recommended, you probably should just create your own db backend module by subclassing or copying the mysql module and placing it inside your project. Remember to update settings.py database configuration to point to your module.

Django admin URL query string "OR". Is it possible?

I love being able to write quick and dirty query strings right into the URL of the Django admin. Like: /admin/myapp/mymodel/?pub_date__year=2011
AND statements are just as easy: /admin/myapp/mymodel/?pub_date__year=2011&author=Jim
I'm wondering if it's possible to issue an 'OR' statement via the URL. Anyone heard of such functionality?
Django < 1.4 doesn't support OR queries. Sometimes it is possible to translate OR queries to __in - queries which are supported (they are equivalent to OR queries but only for single field values).
You can also upgrade to django development version: it has more versatile list_filter implementation (see https://docs.djangoproject.com/en/dev//ref/contrib/admin/#django.contrib.admin.ModelAdmin.list_filter ) which can be used for providing advanced admin filters (including OR-queries).
The & is not a logical AND, even though it seems to be acting that way in your case. I'm pretty certain there is no way to create a logical OR in the GET query string.