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)
Related
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 []>
I am trying to generate a query for which I get the expected result in django shell, but for the same query, I am getting an error that the attribute for the model does not exist.
First the shell:
>>> from dbaccess.models import *
>>> applicantObject = Applicant.objects.get(pk=5)
>>> vol = VolInterview.objects.get(applicant=applicantObject)
>>> vol
<VolInterview: Rajon>
From views.py
from models import *
def addIntCandidate(request):
applicants = Applicant.objects.filter(applicationStatus="Pending")
interviews = Interview.objects.all()
message = []
if request.method == 'POST':
applicant = request.POST.get('applicant')
...
# the value of applicant at this point is 5
applicantObject = Applicant.objects.get(pk=applicant)
prevRejected = VolInterview.objects.get(applicant=applicantObject)
...
Error message:
type object 'VolInterview' has no attribute 'objects'
Traceback:
E:\projects_directory\djangoprojects\kpr-admin-db\dbaccess\views.py in addIntCandidate
prevRejected = VolInterview.objects.get(applicant=applicantObject)
What am I doing wrong?
It looks like you have replaced VolInterview with a different class in your views.
To check, you can add print(VolInterview) to your view and the shell, and check that you get the same result in both.
In Django, it is common to use Form as a suffix for your form classes, e.g. VolInterviewForm, so that the model and form names do not clash.
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)
In Django: I have a date and time that I need to enter into my database model, which has a column models.DateTimeField(). It seems that no matter what I do, I get a ValidationError: enter a valid date/time format.
I have a string like this:
myStr = "2011-10-01 15:26"
I want to do:
p = mytable(myDate = WHAT_GOES_HERE)
p.save()
Please don't point me to a duplicate question. I have looked around and they point to other questions which again point to questions, which point to some documentaton, which just doesn't get me what I need. Thanks!
>>> import datetime
>>> myStr = "2011-10-01 15:26"
>>> WHAT_GOES_HERE = datetime.datetime.strptime(myStr, "%Y-%m-%d %H:%M")
>>> WHAT_GOES_HERE
datetime.datetime(2011, 10, 1, 15, 26)
>>>
datetime.strptime()
From the Django documentation:
# inserting datetime.now()
import django.utils.timezone as tz
mytable.objects.create(myDate=tz.localtime())
# inserting any date:
import pytz
import django.utils.timezone as tz
from datetime import datetime as dt
my_tz = pytz.timezone('Europe/Bucharest')
my_date = dt(2018, 8, 20, 0)
mytable.objects.create(myDate=tz.make_aware(my_date, my_tz))
You can simply do the following
myStr = '2011/10/01 15:26'
And then when creating your object just use myStr as an attribute value:
p = mytable(myDate = myStr)
p.save()
When using a model form:
>>> honest_man.name
u'Abe Lincoln'
>>> form = PersonForm({'name': u'Barack'}, instance=honest_man)
>>> if form.is_valid():
... print('Yay!')
... bankster = form.save()
... else:
... print('Uh Oh :(')
...
Uh Oh :(
>>> honest_man.name # So, we'll just check to be sure nothing changed
u'Barack'
>>> # Oh no, our instance has been corrupted. Now I have to query for it to get
>>> # a clean version without the changes the form made.
>>> honest_man = Person.objects.get(name=u'Abe Lincoln')
>>> # Wasted query because I still need the instance
Is there a way to avoid this (I'm using Django 1.3)?
No, this can't be avoided in 1.3 because of model validation. After cleaning of form fields ModelForm populates instance's fields with cleaned data and calls instance.clean_fields() and instance.clean() methods.