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.
Related
I have a table in DB named Plan.
see code in models.py:
class Plan(models.Model):
id = models.AutoField(primary_key=True)
Comments = models.CharField(max_length=255)
def __str__(self):
return self.Comments
I want to fetch data(comments) from DB and after that data will be deleted. That means one data will be fetched once. And this data will be shown in the Django template.
I tried, see views.py
def Data(request):
data = Plan.objects.filter(id=6)
# latest_id = Model.objects.all().values_list('id', flat=True).order_by('-id').first()
# Plan.objects.all()[:1].delete()
context = {'data':data}
dataD = Plan.objects.filter(id=6)
dataD.delete()
return render(request,'data.html',context)
this code is deleting data from DB but not showing in the template.
How can i do this?
Your template must be updated because it fetch the data from the db one time only so if db is updated your template wouldn't change
From django docs:
Pickling QuerySets¶
If you pickle a QuerySet, this will force all the results to be loaded into memory prior to pickling. Pickling is usually used as a precursor to caching and when the cached queryset is reloaded, you want the results to already be present and ready for use (reading from the database can take some time, defeating the purpose of caching). This means that when you unpickle a QuerySet, it contains the results at the moment it was pickled, rather than the results that are currently in the database.
If you only want to pickle the necessary information to recreate the QuerySet from the database at a later time, pickle the query attribute of the QuerySet. You can then recreate the original QuerySet (without any results loaded) using some code like this:
>>> import pickle
>>> query = pickle.loads(s) # Assuming 's' is the pickled string.
>>> qs = MyModel.objects.all()
>>> qs.query = query # Restore the original 'query'.
I would like to implement a custom Django field type. Namely a TranslatedField that is backed by native json/jsonb using postgres.
But I would also like it to not have to return all translations for a particular query. Something like this:
class TranslatedField(JSONField):
pass
class MyModel(models.Model):
name = TranslatedField()
And then used in an example:
>>> MyModel.objects.create(name={'en': 'Duck', 'fr': 'Canard'})
>>> set_language('fr') # Imagine this function sets a global variable
>>> en_fr = MyModel.objects.get(id=1)
>>> en_fr.name
>>> 'Canard'
Which is fine, I can do that by returning the whole 'name' json from the database. But I would prefer if django issued actual SQL like this that did the lookup in postgres and saved me some bytes across the network:
SELECT 'name'->'fr' FROM 'mymodel';
Does Django have any hooks that let me dynamically change the 'SELECT' part of the query?
consider this code
users = UserProfile.objects.all()[:10]
# evaluate the query set
users_list = list(users)
users = users.prefetch_related('posts')
i want to know that using prefetch_related on queryset after it is evaluated will repeat the query on UserProfile model or not.
Thanks.
No. Until you evaluate it again, as it cannot magically pull the extra data from the database.
>>> from django.db import connection
>>> from app.models import Foo
>>> bar = Foo.objects.all()[:1]
>>> len(connection.queries)
0
>>> bar_list = list(bar)
>>> len(connection.queries)
1
>>> bar = bar.prefetch_related('thing')
>>> len(connection.queries)
1
>>> bar_list = list(bar)
>>> len(connection.queries)
2
No, in this scenario, the query will hit only when you call the variable users.
print users
Hit:
(0.000) QUERY = 'SELECT “userprofile"."id" INNER JOIN “posts" ON ( “userprofile"."usuari...
As explained here, the QuerySet API executes the database query at the first time you iterate over it. In your case the iteration happens because of the list(users).
The prefetch_related function would have an effect on the first query if you would call it before execution.
So, that means: Yes, you can call prefetch_related after iteration, but the QuerySet has to do a new database query to get the missing information about the posts. QuerySets are cloned every time you call a function like prefetch_related. So, the next iteration is the first one for the cloned object.
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.
How do you view the SQL generated by Django for a DELETE?
When doing a SELECT operation on a query set, you can do this:
>>> qs = Entry.objects.filter(date__gt='2010-06-01')
>>> qs.query.as_sql()
('SELECT ...)
But I don't know how to get the SQL for what happens when I do qs.delete().
It looks a bit more involved because Django "emulates the behavior of the SQL constraint ON DELETE CASCADE" when deleting objects.
(Background: trying to debug an IntegrityError generated by a foreign key constraint when deleting a subclassed model object.)
This works well enough:
>>> from django.db import connection
>>> connection.queries[:-10]
Thought the exceptions occurred before the queries were added to connection.queries, but they are indeed present.
Here's another method which relies on Django internals and doesn't include queries to do cascading deletes, but doesn't require executing the query:
from django.db.models import sql
qs = Entry.objects.filter(date__gt='2010-06-01')
query = qs.query.clone()
query.__class__ = sql.DeleteQuery
print(query)
You could try running django-debug-toolbar and see the queries that way.