What is the difference between .get() and .fetch(1) - python

I have written an app and part of it is uses a URL parser to get certain data in a ReST type manner. So if you put /foo/bar as the path it will find all the bar items and if you put /foo it will return all items below foo
So my app has a query like
data = Paths.all().filter('path =', self.request.path).get()
Which works brilliantly. Now I want to send this to the UI using templates
{% for datum in data %}
{{ datum.title }}
{{ datum.content }}
</div>
{% endfor %}
When I do this I get data is not iterable error. So I updated the Django to {% for datum in data.all %} which now appears to pull more data than I was giving it somehow. It shows all data in the datastore which is not ideal. So I removed the .all from the Django and changed the datastore query to
data = Paths.all().filter('path =', self.request.path).fetch(1)
which now works as I intended. In the documentation it says
The db.get() function fetches an
entity from the datastore for a Key
(or list of Keys).
So my question is why can I iterate over a query when it returns with fetch() but can't with get(). Where has my understanding gone wrong?

You're looking at the docs for the wrong get() - you want the get() method on the Query object. In a nutshell, .fetch() always returns a list, while .get() returns the first result, or None if there are no results.

get() requires (I think) that there be exactly one element, and returns it, while fetch() returns a _list_ of the first _n_ elements, where n happens to be 1 in this case.

Related

passing dictionary to view ,with multiple key:value pairs

def status_(request,id):
stages=['Vendor Quotation','Estimate Generation','Purchase Requsition','Purchase Order','Provision To Invoice','Reimbursement Invoice','Request Receipt#(PTI+RI+PO)','Receipt# Received(Updated PTI)','Request Sales Tax Invoice','Uploaded to Jazz Portal']
ctx={'invoice':Invoices.objects.get(pk=id),'stages':stages}
return render(request,"Invoices/status.html",ctx)
Hi I am trying to pass multiple objects of data for displaying to the template for displaying , I am creating a ctx dictionary with multiple 2 key value pairs ,second Key-value pair is array ,when i access this array in by using
{% for idx in range(0,len(ctx.get("stages")) %}
I get following parsing error
**Could not parse the remainder: '(0,len(ctx.get("stages"))' from 'range(0,len(ctx.get("stages"))'**
You can not make function calls in Django templates with parameters, hence the above wiull not work, but likely you do not need this anyway, you can simply enumerate with:
{% for stage in stages %}
{{ stage }}
{% endfor %}
If you really need to enumerate, then you can pass a range object through the context, but then probably a next problem pops up: you can not subscript with a variable either. It will require using a lot of extra template filters, making it very complicated. Templates are normally not used to implement business logic, therefore Django has a template engine that does not support complicated function calls, etc. to give the developer an incentive to move the business logic to the view.

Can I use a variable as index in for loop in python?

I have this for loop on my python template to fulfill an array of values:
labels: [{% for bftimes in dataBF.buffers.0.times %} "{{ bftimes }}", {% endfor %}]
I would like to know if I can use an int variable as an index instead writing it directly, as seen on the code above.
I need to use the index of the selected value of a dropdown:
//returns the index of the selected value
document.getElementById("buffer").selectedIndex
The question needs more context to help us understand your goal. It seems you are mixing python with javascript data structures.
My general recommendation is that you first prepare the python data structure to what you will need and then convert it to json. Looping within Django template language should be used only on simple cases.
If you use django>=2.1 you can use json-script template tag
{{ data|json_script:"my-data" }}
https://docs.djangoproject.com/en/2.1/ref/templates/builtins/#json-script
If not, you can use
# views.py
import json
def foo(request):
dataBF = {"a": [{"c": [1,2,3,1,1]},{"d": [1,2,3,1,1]}]}
# here you can manipulate the data accordingly to what you need
data = json.dumps(dataBF)
return render(request, "index.html", context={"data": data})
On the template side
<script>
const datajs = {{ data | safe }};
</script>
The datajs is a javascript object that you can work with.
I've made an example that you can check https://repl.it/#IvanPereira/python-to-javascript-django-template
You can do this in 2 ways.
Store all values in a list, which JavaScript will consider as json array, and loop over using JavaScript itself. This way you won't be able to update records from server and all values that has to be looped over should be pre-fetched.
You can use AJAX call to pass the selected index from JavaScript and return the new array and update that in the template using JavaScript itself.

Django, how to template aggregate responses

I have series of aggregations in DJANGO that I am performing. What I want to know, is if there is a way to {{ template }} a particular row-value from a dataset.
For example: If I have this dataset response from the server:
[{ type:'O', count:54},{ type:'E', count:125},{ type:'C', count:2}]
Can I reference the counts by type in the template without going through the foreach command?
For example: officers: {{ variable.O.count }} or something like that so I can just directly reference the value in a specific row?
The only other option I have right now, is to call the database three times. And I'm hoping not to have to do that.
Thank you.

How can I limit the number of queries when retrieving all related objects from multiple models?

Lets say I have this model:
class MyLogModel(models.Model):
log_stuff = models.CharField(max_length)
class MoreLogModel(models.Model):
word = models.CharField(max_length)
my_log_model = models.ForeignKey(MyLogModel, related_name="more_log_models")
Now imagine there are 1.000.000.000 MyLogModel and ten times more MoreLogModel which relate to them.
In my view I want to show the user the latest 100 MyLogModel and all the 'word' fields of the MoreLogModel that are relating to them. On average there should be 10 MoreLogModel per MyLogModel.
But if I just use (pseudo code):
my_log_model_query = MyLogModel.objects.get_latest_100
And then loop through it in the template always putting another loop:
{% for my_log in my_log_model_query %}
{% for more_log_model my_log.more_log_models %}
{{ more_log_model.word }}
{% endfor %}
{% endfor %}
That will cause an insane amount of database queries right?
So what I'm wondering is if it is possible to query all MyLogModel with the related "more_log_models" already in a list attached to that model?
The reason why I have the foreign key relationship is because the data comes from a server process that is multi threaded and puts in the "word" whenever it feels like it.
So any ideas how I can solve this problem in general?
Also:
Another way I used before was to have only one model wich has a word field and a group_id. This word field then only contains one word and there is one entry for every word. That causes the 'log_stuff' to be duplicated, but I don't see a big problem with that. What was a huge problem is to go though all these logs and combine them according to the group ids and then sort them based on time again. In the end this causes less queries, but I have to sort everything at least twice which is not very fast.

Why can't iterate through this list in a Django template

I have a variable from my view that is the output of a Model.objects.all() call on that Model. I'm passing it to my template in my view, and I'm trying to iterate over it in the template. I can access the first element of it simply by this line of code. 'code' is the name of a field in my django model. This line does print the first element's 'code' attribute correctly.
{{ var_name.0.code }}
However, when I try to iterate over var_name in a template for loop, nothing shows up. I tried the following code:
{% for single_var in var_name %}
{{ single_var.code }}
{% endfor %}
This isn't actually what I want to do in the for loop, but getting this to work will let me do what I need in the template. It may be noteworthy to add that at the moment this list has only one element in it.
This is for a work project, so that's why I changed the variable names to something generic.
I found that changing the name of single_var to something without an underscore seemed to fix it. This doesn't make a lot of sense to me because the Django template language documentation states the following:
Variable names consist of any combination of alphanumeric characters and the underscore ("_").
Does anyone know why this seemed to fix the problem?

Categories

Resources