Django JSONField - get source text - django

When using a JSONField, the contents are automatically decoded from JSON into python objects when reading the value. I have a use-case where I'm encoding the string back into JSON to embed in a template. Is there any way to just get the raw JSON string from the object?

Django uses psycopg2.extras.Json under the hood. You will need to cast the field as text to get the original out as plain text [1]. Use django's Cast function [2] to annotate your queryset:
from django.db.models.functions import Cast
from django.db.models import TextField
models_with_json_text = Model.objects.annotate(
json_as_text=Cast("json_field_name", TextField())
)
[1] http://initd.org/psycopg/docs/extras.html#json-adaptation
[2] https://docs.djangoproject.com/en/2.2/ref/models/database-functions/#cast

Related

Get max and min formatted date values from queryset in Django

I have a one to many relation between session and camp. Now I have to get the max and min dates of all camps combined for a particular session.
I am able to do it like this:
sess = Session.objects.last()
max_min_dates = sess.camp.aggregate(Min('start_date'), Max('end_date'))
But if I try to send this from HttpResponse then I am getting this error:
TypeError: Object of type 'date' is not JSON serializable
So I need to send the formatted date values in that. How can I modify the above code to get the same?
The default encoder for json.dumps() does not support date encoding (ie. can't convert date into str). You can use django encoder instead, it supports a few more data types see the link for more info.
Django Ref
import json
from django.core.serializers.json import DjangoJSONEncoder
json_str = json.dumps(max_min_dates, cls=DjangoJSONEncoder)

How to test Django JSON-ified ISO8601 Datetime

I'm testing with AjaxResponse with my request factory on a datetime. The problem is the string that Django gives is like this: 2020-08-27T22:46:07.354Z
But when I have datetime object, and I use the isoformat() method, I don't get the same string: 2020-08-27T22:46:07.354734+00:00
How am I going to be able to assert? I'm looking to assert by comparing the JSON with my own Python list (The list is what I can customize).
Thanks to Bast in Discord.py; the datetime conversion is not even iso8601 entirely... it's defined by ECMA-262 which is for JS:
from django.core.serializers.json import DjangoJSONEncoder
DjangoJSONEncoder().default(datetime_obj)
>>> '2020-08-28T03:41:59.194Z'
whereas using the .isoformat() method from standard lib would return 6 rather than 3 decimal points and use +00:00 rather than Z.

Django unable to save a text value in DB

I'm reading an e-mail content through IMAP in my Django app.
When I try to assign some of the parsed content to the object and do .save() it returns:
ProgrammingError: You must not use 8-bit bytestrings unless you use a text_factory that can interpret 8-bit bytestrings (like text_factory = str). It is highly recommended that you instead just switch your application to Unicode strings.
When I print the variable type: . Field in the DB is defined as CharField. I tried TextField as well, but the result is the same.
How I can solve that?
if your mail text is in mail_text, do this:
mail_text = unicode(mail_text)

Get value in a post request, Django

am getting the following post data in my django app
POST
Variable Value
csrfmiddlewaretoken u'LHM3nkrrrrrrrrrrrrrrrrrrrrrrrrrdd'
id u'{"docs":[],"dr":1, "id":4, "name":"Group", "proj":"/al/p1/proj/2/", "resource":"/al/p1/dgroup/4/","route":"group", "parent":null'
am trying to get the id value in variable id i.e "id":4 (the value 4). When I do request.POST.get('id')I get the whole json string. u'{"docs":[],"dr":1, "id":4, "name":"Group", "proj":"/al/p1/proj/2/", "resource":"/al/p1/dgroup/4/","route":"group", "parent":null' How can I get the "id" in the string?
The data you are sending is simply a json string.
You have to parse that string before you can access data within it. For this you can use Python's json module (it should be available if you're using Python 2.7).
import json
data = json.loads( request.POST.get('id') )
id = data["id"]
If you somehow don't have the json module, you can get the simplejson module.
For more details, refer this question : best way to deal with JSON in django
That's happening because id is string, not dict as it should be. Please provide your template and view code to find source of problem.

How to insert a row of data to a table using Django's ORM

How do I insert data in Django to a SQL table using the Django ORM?
If you need to insert a row of data, see the "Saving objects" documentation for the save method on the model.
FYI, you can perform a bulk insert. See the bulk_create method's documentation.
In fact it's mentioned in the first part of the "Writing your first Django app" tutorial.
As mention in the "Playing with API" section:
>>> from django.utils import timezone
>>> p = Poll(question="What's new?", pub_date=timezone.now())
# Save the object into the database. You have to call save() explicitly.
>>> p.save()
# Now it has an ID. Note that this might say "1L" instead of "1", depending
# on which database you're using. That's no biggie; it just means your
# database backend prefers to return integers as Python long integer
# objects.
>>> p.id
1
Part-4 of the tutorial explains how to use forms and how to save object using user submitted data.
If you don't want to call the save() method explicitly, you can create a record by using MyModel.objects.create(p1=v1, p2=v1, ...)
fruit = Fruit.objects.create(name='Apple')
# get fruit id
print(fruit.id)
See documentation