I am using Django 1.3 and trying to use .exists() on a model entry but get the error listed below. Exists() was included in Django 1.2 so I should have access to it. I verified my version using django.get_version and it was okay.
Querying MyModel based on pk only returns an entry but querying with .exists() throws an error. Do I need to imports something?
>>> m = MyModel.objects.get(pk=1)
>>> m
<MyModel: Model field entry 1>
>>> m = MyModel.objects.get(pk=1).exists()
Traceback (most recent call last):
File "<console>", line 1, in <module>
AttributeError: 'MyModel' object has no attribute 'exists'
exists() is a method of a QuerySet.
get() returns a single model instance, and will raise an exception Entry.DoesNotExist if that instance doesn't exist. So you'll need to wrap this in a try/except block if you're not sure if an instance with that id exists.
I'm using Django 1.7 on my project and my codes like :
try:
temp_query_set = YourModelName.functionName()
except ObjectDoesNotExists:
<do something>
note that, my code (at first) using if query_set.exists()
it works fine when there is no query set returned, but raise error object does not have attribute 'exists' when there is something returned.
so pls try avoid using if <something>.exists()
CMIIW
try use .filter() instead .get(), like this:
m = MyModel.objects.filter(pk=1).exists()
y = MyModel.objects.filter(pk=2).exists()
print(m)
print(y)
output must to be a bool, exemple:
False
True
suposing that m does not exist and y exists
Related
I have a Django class as follows:
class MyModel(models.Model):
my_int = models.IntegerField(null=True, blank=True,)
created_ts = models.DateTimeField(default=datetime.utcnow, editable=False)
When I run the following queryset, I get an error:
>>> from django.db.models import Max, F, Func
>>> MyModel.objects.all().aggregate(Max(Func(F('created_ts'), function='UNIX_TIMESTAMP')))
Traceback (most recent call last):
File "<console>", line 1, in <module>
File "MyVirtualEnv/lib/python2.7/site-packages/django/db/models/query.py", line 297, in aggregate
raise TypeError("Complex aggregates require an alias")
TypeError: Complex aggregates require an alias
How do I adjust my queryset so that I don't get this error?
I want to find the instance of MyModel with the latest created_ts. And I want to use the UNIX_TIMESTAMP function to get it.
I'm not running the same Django version, but I think this'll work:
MyModel.objects.all().aggregate(latest=Max(Func(F('created_ts'), function='UNIX_TIMESTAMP')))
Note the latest keyword argument in there. That's the key (I think, again I can't test this).
From the django docs:
aggregate() is a terminal clause for a QuerySet that, when invoked,
returns a dictionary of name-value pairs
It will automatically provide this value in many generic cases, e.g.
Sum('items') -> sum_items
For your query, it cannot create a default alias, so you must provide one. This is so the query can return a named result for the values produced. All you have to do is give your aggregate a meaningful named alias and all should work fine:
MyModel.objects.all().aggregate(max_created=Max(Func(F('created_ts'), function='UNIX_TIMESTAMP')))
just need set name for result variable :
see item in below code
result = MyModel.objects.all().aggregate(item=Max(Func(F('created_ts'), function='UNIX_TIMESTAMP')))
result.get('item')
How can I check, which query django 1.4.11 generates for this query:
obj = Model.objects.get(code='code')
I've tried:
print Model.objects.get(code='code').query
but there is such method for model object.
How can I get raw sql?
It doesn't work because query is a property of the Queryset object and when you do a .get() the Queryset it´s evaluated (and became an instance of Model)
If you try:
>>> type(Model.objects.get(code='code'))
<class 'app.models.Model'>
>>> print Model.objects.get(code='code').query
AttributeError: 'Model' object has no attribute 'query'
But instead with:
>>> type(Model.objects.all())
<class 'django.db.models.query.QuerySet'>
>>> print Model.objects.all().query
SELECT "model.Model" from ...
Now, to get the SQL of all the queries you have several options:
If DEBUG=True you can use this:
from django.db import connection
print connection.queries
Use django-debug-toolbar
Use the built-in django logging https://docs.djangoproject.com/en/dev/topics/logging/#django-db-backends You can find examples on how to setup here in SO.
I am going through the creation of the Polls app again, in the Django Docs. I wanted to ask again about one particular thing they do in the django database. The code is shown below:
>>> from polls.models import Poll, Choice
# Make sure our __unicode__() addition worked.
>>> Poll.objects.all()
[<Poll: What's up?>]
# Django provides a rich database lookup API that's entirely driven by
# keyword arguments.
>>> Poll.objects.filter(id=1)
[<Poll: What's up?>]
>>> Poll.objects.filter(question__startswith='What')
[<Poll: What's up?>]
# Get the poll that was published this year.
>>> from django.utils import timezone
>>> current_year = timezone.now().year
>>> Poll.objects.get(pub_date__year=current_year)
<Poll: What's up?>
# Request an ID that doesn't exist, this will raise an exception.
>>> Poll.objects.get(id=2)
Traceback (most recent call last):
...
DoesNotExist: Poll matching query does not exist. Lookup parameters were {'id': 2}
# Lookup by a primary key is the most common case, so Django provides a
# shortcut for primary-key exact lookups.
# The following is identical to Poll.objects.get(id=1).
>>> Poll.objects.get(pk=1)
<Poll: What's up?>
# Make sure our custom method worked.
>>> p = Poll.objects.get(pk=1)
>>> p.was_published_recently()
True
# Give the Poll a couple of Choices. The create call constructs a new
# Choice object, does the INSERT statement, adds the choice to the set
# of available choices and returns the new Choice object. Django creates
# a set to hold the "other side" of a ForeignKey relation
# (e.g. a poll's choices) which can be accessed via the API.
>>> p = Poll.objects.get(pk=1)
# Display any choices from the related object set -- none so far.
>>> p.choice_set.all()
[]
# Create three choices.
>>> p.choice_set.create(choice_text='Not much', votes=0)
<Choice: Not much>
>>> p.choice_set.create(choice_text='The sky', votes=0)
<Choice: The sky>
>>> c = p.choice_set.create(choice_text='Just hacking again', votes=0)
# Choice objects have API access to their related Poll objects.
>>> c.poll
<Poll: What's up?>
If you take a look at the variable c, you will see that it is created using this, p.choice_set.create(choice_text='Just hacking again', votes=0). Now if you created it instead with this: c = p.choice_set.filter(id=3), and when you type in c.poll, it will give you an error. Why does this happen? The console gives me this error : AttributeError: 'Poll' object has no attribute 'create', but I do not understand what it means.
Also, is there any way of getting c.poll to give you an output without having to create a new choice?
--
Thanks in advance
c = p.choice_set.filter(id=3) won't return a single choice object. It returns a queryset composed of a single choice object because, obviously, there is just one object with the same id. Querysets are iterables, which means that if you want to obtain the choice object from that variable it should be: c = p.choice_set.filter(id=3)[0]
That is the difference with choice_set.create: create returns the single created object.
Now, that's not the way to do it. When you know you are querying for a single object, use get.
c = p.choice_set.get(id=3).
See querying documentation for further details.
I've added a model boolean field called 'is_dotcom' to my admin list_display, and the implementation is:
email = models.EmailField(max_length=254)
def is_dotcom(self):
return self.email.lower().endsWith(".com")
is_dotcom.admin_order_field = 'email'
is_dotcom.boolean = True
is_dotcom.short_description = 'Company?'
But all this yields on my admin page is "(None)". I'm expecting True/False (though sometimes my booleans show as a green check or red no entry sign, anyone know why that is?)
I've based this code on an example in the django tutorial.
I'm assuming that "(None)" is being shown because the is_dotcom() method is raising an AttributeError which django is catching. I'm guessing that it's legal to call .lower() on an EmailField but I don't know for sure (what do you guys do for reference documentation?) Thanks.
The problem is in this line:
return self.email.lower().endsWith(".com")
The method is .endswith().
Please note the absence of camel-case.
A simplified example which reproduces the error:
>>> 'foo'.endsWith('test')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'str' object has no attribute 'endsWith'
I have noticed with model objects in django that I can do:
MyModel.objects.all()
I can do this without making a new MyModel object. How/why does this work?
Edited the question:
I am not asking about the base Model class, but I am talking about a model called MyModel that extends from the base Model class
What is Model.objects
Model classes, have a Manager class, you can get it like this:
YourModel.objects
The Manager is the one making SQL queries, for example, this will return a QuerySet:
YourModel.objects.all()
A QuerySet behaves mostly like a normal python list, except that it will make an SQL query when it is first evaluated.
The base model class has no manager !
So you cannot do Model.objects.all() as you said:
In [1]: from django.db.models import Model
In [2]: Model.objects
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
/home/jpic/env/local/lib/python2.7/site-packages/django/core/management/commands/shell.pyc in <module>()
----> 1 Model.objects
AttributeError: type object 'Model' has no attribute 'objects'
A QuerySet will fail if the table doesn't exist !
It will throw a DatabaseError:
50 def execute(self, query, args=None):
51 try:
---> 52 return self.cursor.execute(query, args)
53 except Database.IntegrityError, e:
54 raise utils.IntegrityError, utils.IntegrityError(*tuple(e)), sys.exc_info()[2]
DatabaseError: relation "formapp_testmodel" does not exist
LINE 1: SELECT "formapp_testmodel"."id" FROM "formapp_testmodel" LIM...
If you define a model class MyModel(models.Model) and then run python manage.py syncdb, django will create a databse table yourapp_mymodel. You can run queries against that db table that return no tuples, so you can create a queryset that contains no results - eg MyModel.objects.none().
The queryset api would be pretty hopeless if it threw an exception every time you ran a query that returned no results.
(I've assumed that you meant to ask why you can do MyModel.objects.all() rather than Model.objects.all(). As jpic shows in his answer you can't do Model.objects.all().