get most recent rows stored in related tables using django [duplicate] - python

I've got 2 questions, but they are related to the same topic.
I know how to retrieve data from a for loop using template tags
{% for status in status %}
<tr>
<td>{{ status.status}}</td>
</tr>
{% endfor %}
However when I want to retrieve a single object i get an error even when i use:
po = Status.objects.latest('id')
and remove the for loop.
I get:
'Status' object is not iterable
My questions are:
How can I get the latest entry from the database for a given model?
How can I setup my templates tags to allow for just a single record?

You have two different questions here:
How do I retrieve the latest object from the database.
You can do this using the latest() queryset operator. By reading the docs you will note that this operator works on date fields, not integers.
Status.objects.latest('date_added') # or date_updated
If you want to do this off the ID you will need to order by ID and select the first result. (this will only work if you are using incrementing primary keys, it will not work with UUID's or randomly generated hashes).
Status.objects.order_by('id')[0]
Side note: I would personally use the date_added / date_updated way of doing this.
Iterating over a single object
A single object cannot be iterated over. For this you will need to use a different template. Or, you will need to add the single object into a list.
# note the [] around the query
result = [Status.object.latest('date_added')]
Personally I have a different views for listing single / multiple result. I have a ListView for many result objects and a DetailView for single objects.

TableName.objects.filter(key=value).order_by('-date_filed').first()
The "-date_filed'" field will reverse the order and the first will give you the latest element.

Let us assume I have a Model named "OneOfTheModelsUsed"
and there is a field called "car_name" and "date" within this model.
The following code worked for me while I was using Django FormWizard. After going through all the steps in the form and it gets saved. I used
last_entry = OneOfTheModelsUsed.objects.latest("date")
This gives all the entries in that model
last_car_name = last_entry.car_name
This gives the specific field entry you want in the given form.
return render(request, 'reference.html', {'last_car_name':last_car_name,}
passed the data to a template.
for the display in the template I used
{{last_car_model}}
and if you need the id for that entry.. use this {{last_car_model.id}} in the template.
PS:I'm fairly new to Django and Web development as a whole so I don't know much of the technical terms for all this

This is because latest returns a single instance rather than a queryset (which is iterable). So:
1) Latest is not working because it works with Date Fields. Read more at: https://docs.djangoproject.com/en/1.8/ref/models/querysets/#latest. 'id' is not a valid field to use with the latest filter.
2) You can't use for template tag with a single instance because it is not iterable.
To solve your situation, I would specify the ordering = ('id',) field in the Meta class of the model and then do a po = Status.objects.all()[:1] so you will obtain a queryset (which is iterable) with a single object in it. Then you will be able to use the for template tag with your po variable.
Hope it helps.

comments = usercomment.objects.order_by('-id')[:100]
I Did By This Method
First "comment" Is The Variable Name, "usercomment" Is Model Name, "id" is generated by django when make a model, [:100] is from 0 to 100 you can increase the number to x

Related

Extract only the data from a Django Query Set

I am working to learn Django, and have built a test database to work with. I have a table that provides basic vendor invoice information, so, and I want to simply present a user with the total value of invoices that have been loaded to into the database. I found that the following queryset does sum the column as I'd hoped:
total_outstanding: object = Invoice.objects.aggregate(Sum('invoice_amount'))
but the result is presented on the page in the following unhelpful way:
Total $ Outstanding: {'invoice_amount__sum': Decimal('1965')}
The 1965 is the correct total for the invoices that I populated the database with, so the queryset is pulling what I want it to, but I just want to present that portion of the result to the user, without the other stuff.
Someone else asked a similar question (basically the same) here: how-to-extract-data-from-django-queryset, but the answer makes no sense to me, it is just:
k = k[0] = {'name': 'John'}
Queryset is list .
Can anyone help me with a plain-English explanation of how I can extract just the numerical result of that query for presentation to a user?
What you here get is a dictionary that maps the name of the aggregate to the corresponding value. You can use subscripting to obtain the corresponding value:
object = Invoice.objects.aggregate(
Sum('in,voice_amount')
)['invoice_amount__sum']

Saving and updating nested documents with MongoEngine

I want to implement this structural model to store my data on Mongodb with MongoEngine on flask:
skills = [{"asm":"Assembly",
"flag":False,
"date": datetime},
{"java":"Java",
"flag":False,
"date": datetime}]
So I don't know how I can declare and update this kind of structure.
For updating one object I used:
User.objects(skills=form.skills.data).update_one()
However, I don't know how to update more fields in one shot.
I tried with the code below but it doesn’t work.
now = datetime.now()
User.objects(skills=form.skills).update_one(set__skills = ({'ruby':'Ruby'}, {'flag':'true'},{'date':now}))
What kind of fields should I declare on forms.py?
For what I understood, you need a a nested document (skills) into another (who refers to User in this case). For doing something like this you don't have to update atomically a field but append values to the subdocument and the save everything.
Tryin' to follow your example, in your case should do something like this:
user = User.objects(email=current_user.email).get()
To get the BaseQuery that refers to user X through a certain query filter, in my example the email of the current logged user
user.kskills.append(SubDocumentClass(skillName="name_of_the_skill", status=True, date=datetime.now()))
For append a collection to the subdocument list. (I've appended your field)
user.save()
To save everything

Django Get Latest Entry from Database

I've got 2 questions, but they are related to the same topic.
I know how to retrieve data from a for loop using template tags
{% for status in status %}
<tr>
<td>{{ status.status}}</td>
</tr>
{% endfor %}
However when I want to retrieve a single object i get an error even when i use:
po = Status.objects.latest('id')
and remove the for loop.
I get:
'Status' object is not iterable
My questions are:
How can I get the latest entry from the database for a given model?
How can I setup my templates tags to allow for just a single record?
You have two different questions here:
How do I retrieve the latest object from the database.
You can do this using the latest() queryset operator. By reading the docs you will note that this operator works on date fields, not integers.
Status.objects.latest('date_added') # or date_updated
If you want to do this off the ID you will need to order by ID and select the first result. (this will only work if you are using incrementing primary keys, it will not work with UUID's or randomly generated hashes).
Status.objects.order_by('id')[0]
Side note: I would personally use the date_added / date_updated way of doing this.
Iterating over a single object
A single object cannot be iterated over. For this you will need to use a different template. Or, you will need to add the single object into a list.
# note the [] around the query
result = [Status.object.latest('date_added')]
Personally I have a different views for listing single / multiple result. I have a ListView for many result objects and a DetailView for single objects.
TableName.objects.filter(key=value).order_by('-date_filed').first()
The "-date_filed'" field will reverse the order and the first will give you the latest element.
Let us assume I have a Model named "OneOfTheModelsUsed"
and there is a field called "car_name" and "date" within this model.
The following code worked for me while I was using Django FormWizard. After going through all the steps in the form and it gets saved. I used
last_entry = OneOfTheModelsUsed.objects.latest("date")
This gives all the entries in that model
last_car_name = last_entry.car_name
This gives the specific field entry you want in the given form.
return render(request, 'reference.html', {'last_car_name':last_car_name,}
passed the data to a template.
for the display in the template I used
{{last_car_model}}
and if you need the id for that entry.. use this {{last_car_model.id}} in the template.
PS:I'm fairly new to Django and Web development as a whole so I don't know much of the technical terms for all this
This is because latest returns a single instance rather than a queryset (which is iterable). So:
1) Latest is not working because it works with Date Fields. Read more at: https://docs.djangoproject.com/en/1.8/ref/models/querysets/#latest. 'id' is not a valid field to use with the latest filter.
2) You can't use for template tag with a single instance because it is not iterable.
To solve your situation, I would specify the ordering = ('id',) field in the Meta class of the model and then do a po = Status.objects.all()[:1] so you will obtain a queryset (which is iterable) with a single object in it. Then you will be able to use the for template tag with your po variable.
Hope it helps.
comments = usercomment.objects.order_by('-id')[:100]
I Did By This Method
First "comment" Is The Variable Name, "usercomment" Is Model Name, "id" is generated by django when make a model, [:100] is from 0 to 100 you can increase the number to x

How can I make a Django query for the first occurrence of a foreign key in a column?

Basically, I have a table with a bunch of foreign keys and I'm trying to query only the first occurrence of a particular key by the "created" field. Using the Blog/Entry example, if the Entry model has a foreign key to Blog and a foreign key to User, then how can I construct a query to select all Entries in which a particular User has written the first one for the various Blogs?
class Blog(models.Model):
...
class User(models.Model):
...
class Entry(models.Model):
blog = models.Foreignkey(Blog)
user = models.Foreignkey(User)
I assume there's some magic I'm missing to select the first entries of a blog and that I can simple filter further down to a particular user by appending:
query = Entry.objects.magicquery.filter(user=user)
But maybe there's some other more efficient way. Thanks!
query = Entry.objects.filter(user=user).order_by('id')[0]
Basically order by id (lowest to highest), and slice it to get only the first hit from the QuerySet.
I don't have a Django install available right now to test my line, so please check the documentation if somehow I have a type above:
order by
limiting querysets
By the way, interesting note on 'limiting queysets" manual section:
To retrieve a single object rather
than a list (e.g. SELECT foo FROM bar
LIMIT 1), use a simple index instead
of a slice. For example, this returns
the first Entry in the database, after
ordering entries alphabetically by
headline:
Entry.objects.order_by('headline')[0]
EDIT: Ok, this is the best I could come up so far (after yours and mine comment). It doesn't return Entry objects, but its ids as entry_id.
query = Entry.objects.values('blog').filter(user=user).annotate(Count('blog')).annotate(entry_id=Min('id'))
I'll keep looking for a better way.
Ancient question, I realise - #zalew's response is close but will likely result in the error:
ProgrammingError: SELECT DISTINCT ON expressions must match initial
ORDER BY expressions
To correct this, try aligning the ordering and distinct parts of the query:
Entry.objects.filter(user=user).distinct("blog").order_by("blog", "created")
As a bonus, in case of multiple entries being created at exactly the same time (unlikely, but you never know!), you could add determinism by including id in the order_by:
To correct this, try aligning the ordering and distinct parts of the query:
Entry.objects.filter(user=user).distinct("blog").order_by("blog", "created", "id")
Can't test it in this particular moment
Entry.objects.filter(user=user).distinct("blog").order_by("id")

In Django, how does one filter a QuerySet with dynamic field lookups?

Given a class:
from django.db import models
class Person(models.Model):
name = models.CharField(max_length=20)
Is it possible, and if so how, to have a QuerySet that filters based on dynamic arguments? For example:
# Instead of:
Person.objects.filter(name__startswith='B')
# ... and:
Person.objects.filter(name__endswith='B')
# ... is there some way, given:
filter_by = '{0}__{1}'.format('name', 'startswith')
filter_value = 'B'
# ... that you can run the equivalent of this?
Person.objects.filter(filter_by=filter_value)
# ... which will throw an exception, since `filter_by` is not
# an attribute of `Person`.
Python's argument expansion may be used to solve this problem:
kwargs = {
'{0}__{1}'.format('name', 'startswith'): 'A',
'{0}__{1}'.format('name', 'endswith'): 'Z'
}
Person.objects.filter(**kwargs)
This is a very common and useful Python idiom.
A simplified example:
In a Django survey app, I wanted an HTML select list showing registered users. But because we have 5000 registered users, I needed a way to filter that list based on query criteria (such as just people who completed a certain workshop). In order for the survey element to be re-usable, I needed for the person creating the survey question to be able to attach those criteria to that question (don't want to hard-code the query into the app).
The solution I came up with isn't 100% user friendly (requires help from a tech person to create the query) but it does solve the problem. When creating the question, the editor can enter a dictionary into a custom field, e.g.:
{'is_staff':True,'last_name__startswith':'A',}
That string is stored in the database. In the view code, it comes back in as self.question.custom_query . The value of that is a string that looks like a dictionary. We turn it back into a real dictionary with eval() and then stuff it into the queryset with **kwargs:
kwargs = eval(self.question.custom_query)
user_list = User.objects.filter(**kwargs).order_by("last_name")
Additionally to extend on previous answer that made some requests for further code elements I am adding some working code that I am using
in my code with Q. Let's say that I in my request it is possible to have or not filter on fields like:
publisher_id
date_from
date_until
Those fields can appear in query but they may also be missed.
This is how I am building filters based on those fields on an aggregated query that cannot be further filtered after the initial queryset execution:
# prepare filters to apply to queryset
filters = {}
if publisher_id:
filters['publisher_id'] = publisher_id
if date_from:
filters['metric_date__gte'] = date_from
if date_until:
filters['metric_date__lte'] = date_until
filter_q = Q(**filters)
queryset = Something.objects.filter(filter_q)...
Hope this helps since I've spent quite some time to dig this up.
Edit:
As an additional benefit, you can use lists too. For previous example, if instead of publisher_id you have a list called publisher_ids, than you could use this piece of code:
if publisher_ids:
filters['publisher_id__in'] = publisher_ids
Django.db.models.Q is exactly what you want in a Django way.
This looks much more understandable to me:
kwargs = {
'name__startswith': 'A',
'name__endswith': 'Z',
***(Add more filters here)***
}
Person.objects.filter(**kwargs)
A really complex search forms usually indicates that a simpler model is trying to dig it's way out.
How, exactly, do you expect to get the values for the column name and operation?
Where do you get the values of 'name' an 'startswith'?
filter_by = '%s__%s' % ('name', 'startswith')
A "search" form? You're going to -- what? -- pick the name from a list of names? Pick the operation from a list of operations? While open-ended, most people find this confusing and hard-to-use.
How many columns have such filters? 6? 12? 18?
A few? A complex pick-list doesn't make sense. A few fields and a few if-statements make sense.
A large number? Your model doesn't sound right. It sounds like the "field" is actually a key to a row in another table, not a column.
Specific filter buttons. Wait... That's the way the Django admin works. Specific filters are turned into buttons. And the same analysis as above applies. A few filters make sense. A large number of filters usually means a kind of first normal form violation.
A lot of similar fields often means there should have been more rows and fewer fields.

Categories