I would like to know how I can get ("decode?") the data from a JsonField, I'm having this:
{"pleople": "name=Jhon&email=email#domain.com", "id": 251304}
How I can pass this to my view like name['Jhon'] or any kind of object to use with querySet or parameter?
>>> from urlparse import parse_qs, parse_qsl
>>> parse_qs("name=Jhon&email=email#domain.com")
{'email': ['email#domain.com'], 'name': ['Jhon']} # allow multiple values
>>> dict(parse_qsl("name=Jhon&email=email#domain.com"))
{'email': 'email#domain.com', 'name': 'Jhon'} # dict w/ single value
Or you could use django.http.QueryDict directly
>>> from django.http import QueryQict
>>> QueryDict("name=Jhon&email=email#domain.com")
<QueryDict: {u'name': [u'Jhon'], u'email': [u'email#domain.com']}>
Related
I have a simple serializer with a date field (not ModelSerializer).
class MySerializer(Serializer):
some_date = DateField()
I'm trying to access the date object after deserialization.
slz = MySerializer(data={"some_date": "2020-05-03"})
# I surely have a better error handling in my actual code
assert slz.is_valid()
some_extracted_date = slz.data["some_date"]
I would like my variable some_extracted_date to be a datetime.date instance.
But the value in the MySerializer.data dict is a string.
Is there a way to get this datetime.date instance ?
You access data after validation using validated_data.
>>> from app.models import MySerializer
>>> slz = MySerializer(data={"some_date": "2020-05-03"})
>>> slz.is_valid(True)
True
>>> slz.data
{'some_date': '2020-05-03'}
>>> slz.validated_data
OrderedDict([('some_date', datetime.date(2020, 5, 3))])
>>> slz.validated_data['some_date']
datetime.date(2020, 5, 3)
As per documentation 'contains' field lookup is case-sensitive and 'icontains' is case-Insensitive, but I don't see any difference while i'm querying it.
>>> from users.models import SnetUser
>>> SnetUser.objects.get(email__contains='Satti')
<SnetUser: satti>
>>> SnetUser.objects.get(email__contains='satti')
<SnetUser: satti>
>>> obj = SnetUser.objects.get(email__contains='satti')
>>> obj.email
'satti#gmail.com'
Both are resulting same.
Note: I'm using django's SQLite DB locally
This case is written in the docs.
contains field lookup is being converted to LIKE clause and in SQLite it is case-insensitive.
In case you want to make LIKE clause to work case-sensitively, you need to use the following PRAGMA:
PRAGMA case_sensitive_like = true;
>>> from django.db import connection
>>> with connection.cursor() as cursor:
... cursor.execute('PRAGMA case_sensitive_like = true;')
>>> SnetUser.objects.get(email__contains='Satti')
<QuerySet []>
to be brief, i have this queryset:
monthly_revenue = list(Booking.objects.annotate(month=Month('created_at'))
.values('month')
.annotate(total=Sum('price'))
.order_by('month'))
this is what it is returning:
[{'month': 11, 'total': Decimal('4550.00')}]
the result is going to a js script to show a graph, and i need to remove the Decimal() prefix.
Any help or hint is appreciated.
If you just want to remove "Decimal" prefix you could just define a specific output field in your annotation:
monthly_revenue = list(Booking.objects.annotate(month=Month('created_at'))
.values('month')
.annotate(total=Sum('price', output_field=FloatField()))
.order_by('month'))
Since you're using Django you can use DjangoJSONEncoder as follows:
from django.core.serializers.json import DjangoJSONEncoder
my_dict = [{'month': 11, 'total': Decimal('4550.00')}]
json_result = json.dumps(my_dict, cls=DjangoJSONEncoder)
But, keep in mind that DjangoJSONEncoder turns decimal into strings so the result would be:
[{"month": 11, "total": "4550.00"}]
If you navigate to DjangoJSONEncoder source code you find this:
elif isinstance(o, (decimal.Decimal, uuid.UUID, Promise)):
return str(o)
you could convert it to a type float, like this
monthly_revenue = list(Booking.objects.annotate(month=Month('created_at'))
.values('month')
.annotate(total=float(Sum('price')))
.order_by('month'))
I finally found two solutions that worked for me:
Thanks to #Ramy's answer, I overidden the DjangoJSONEncoder, to support the conversion of a Decimal to a float:
import decimal
import uuid
from django.utils.functional import Promise
from django.core.serializers.json import DjangoJSONEncoder
class JsonDecimalToFloatEncoder(DjangoJSONEncoder):
def default(self, o):
if isinstance(o, (decimal.Decimal, uuid.UUID, Promise)):
return float(o)
return super().default(o)
and I used it as he mentioned:
monthly_revenue = list(Booking.objects.annotate(month=Month('created_at'))
.values('month')
.annotate(total=Sum('price'))
.order_by('month'))
json_result = json.dumps(monthly_revenue,cls=ExtendedEncoder)
json_result
'[{"month": 11, "total": 4550.0}]'
this solution requires more work on the server side, so i opted for the second solution of #rossi which does more work on the database rather than the server, and that's what the django's documentation suggest.
from django.db.models import FloatField
from django.db.models.functions import Cast
list(Booking.objects.annotate(month=Month('created_at'))
.values('month')
.annotate(total_as_f=Cast('total',
output_field=FloatField()))
.order_by('month'))
[{'month': 11, 'total': Decimal('4550.00'), 'total_as_f': 4550.0}]
hope this will help anyone in the futur.
I'm trying to get data in a view formatted to json to pass to jQuery code.
I am able to get a json dump from a simple dictionary:
from django.core import serializers
message = Message.objects.get(pk=2)
json_result = serializers.serialize("json", [message,])
I am also able to get a json dump from a Django model:
import json
result = {"message": "hello",
"age": 3}
json_result = json.dumps(result)
but I haven't been able to get a properly formatted json dump from a Django model nested inside a dictionary:
from django.core import serializers
import json
message = Message.objects.get(pk=2)
json_message = serializers.serialize("json", [message,])
result = {"message": json.dumps(serialized_message),
"age": 3}
bad_json_result = json.dumps(result)
You can use json.loads
import json
from django.core import serializers
message = Message.objects.get(pk=2)
json_str_result = serializers.serialize("json", [message,]) #returns string
to_dump = {"message": json.loads(json_str_result)[0], "age": 3} #json.loads
print json.dumps(to_dump)
In Django filter statement what's the difference if I write:
.filter(name__exact='Alex')
and
.filter(name='Alex')
Thanks
There is no difference, the second one implies using the __exact.
From the documentation:
For example, the following two statements are equivalent:
>>> Blog.objects.get(id__exact=14) # Explicit form
>>> Blog.objects.get(id=14)
# __exact is implied This is for convenience, because exact
# lookups are the common case.
You can look at the SQL that Django will execute by converting the queryset's query property to a string:
>>> from django.contrib.auth.models import User
>>> str(User.objects.filter(username = 'name').query)
'SELECT ... WHERE `auth_user`.`username` = name '
>>> str(User.objects.filter(username__exact = 'name').query)
'SELECT ... WHERE `auth_user`.`username` = name '
So __exact makes no difference here.
This is not exactly the same as the question but can be useful for some developers.
It depends on Django database and collation. I am using mysql db and ci(case insensitive) collation and have a strange result.
If there is User "Test" and query with space in the end
In : User.objects.filter(username__iexact="Test ")
Out : <QuerySet []>
In : User.objects.filter(username__exact="Test ")
Out : <QuerySet [<User: Test>]>
In : User.objects.filter(username="Test ")
Out : <QuerySet [<User: Test>]>
from django.test import TestCase
from user.factories import UserFactory
from user.models import User
class TestCaseSensitiveQueryTestCase(TestCase):
def setUp(self):
super().setUp()
self.QUERY = 'case sensitive username'
self.USERNAME = 'cAse SEnSItIVE UsErNAME'
self.user = UserFactory(name=self.USERNAME)
def test_implicit_exact_match(self):
with self.assertRaises(User.DoesNotExist):
User.objects.get(name=self.QUERY)
def test_explicit_iexact_match(self):
User.objects.get(name__iexact=self.QUERY)