I'm using Google App Engine 1.8.3 - Python 2.7 and NDB API as my datastore
Suppose I have a list of group entities displayed on a html table.
And I want to click the name of an individual group to edit the group's information.
What should the key/id of this group be, which one should I use? Please take a look at below
Here's my Model:
class Group(ndb.Model):
name = ndb.StringProperty()
description = ndb.StringProperty()
In my html:
......
{% for group in groups %}
<tr>
<td>
<a href="/editGroup?id={{ ????????????? }}" {{ group.name}} </a>
</td>
<td>
{{ group.description}}
</td>
</tr>
{% endfor %}
......
In the ????? inside the <a> tag, what should I put? what should I pass it back to the server? group.key? group.key.id()? or I have to add the Property to Group model as a key property like groupId = ndb.IntegerProperty()?
I'm thinking about using the entity's key, but I couldn't find a way to display the key in the html from 'group', like group.something_to_get_the_key().
I was able to get the numeric id using group.key.id(), but according to https://developers.google.com/appengine/docs/python/ndb/entities#numeric_keys
numeric ids might not be unique.
Thanks
In NDB, keys have a urlsafe() method which produces a string suitable for use in templates and passing to URLs:
{{ group.key.urlsafe }}
This is documented on the same page you already link to.
Related
I have a flask webpage I am trying to create. When users register for an account, they declare the number of agricultural fields they have. This is saved in a MySQL database. From this, I need users to add information on another input page. This input page should have "n" number of textboxes based on the number of fields they have.
Is there anyway to create "n" number of textboxes in HTML? I can read in the number of fields from their account but cannot find a way to create a variable number of textboxes within HTML.
I do not need this to be dynamic (the user add or remove) this needs to be a FIXED amount of textboxes.
I'm going to assume that because of flask you are using jina2 as your rendering engine, let's call the number of fields that need to be created n, you can just use the loop structure
{% for i in range(n) %}
<input name="field-{{i}}" />
{% endfor %}
you can get more info at https://jinja.palletsprojects.com/en/3.0.x/templates/#for
if you need more complex forms, I would recommend using WTForms.
Found a solution, it is a little ugly but should work.
in your html:
<table>
{% for x in range(fields | int) %}
<tr>
<td>
<input type="text" value="{{ x }}">
</td>
</tr>
{% endfor %}
</table>
in python:
def irrigation_input():
...... non important stuff here.....
fields=account_info_irr[9]
int(float(fields))
return render_template('irrigationinput.html',fields=fields)
I have a query that I do in my view to get a bunch of team stat objects...
team_stats = NCAABTeamStats.objects.filter(
name__name__in=teams_playing).order_by(sort)
One of the fields 'name' is a foreign key. I pass team_stats to my template to display the data in a chart via a 'for loop'.
{% for team in team_stats %}
<tr>
<td>
{{ team.name }}
</td>
</tr>
{% endfor %}
So in my template, for every object in team_stats it is doing a query when it prints {{ team.name }} and it really slows things down, especially when there are 50-100 teams.
My question is, is there a way to print 'team.name' without it doing a query every time?
if it is a foreignkey you can do something like this
team_stats=NCAABTeamStats.objects.select_related('name').filter(name__name__in=teams_playing).order_by(sort)
you can learn more on select_related here
if it is a manytomany field you can do something like this
team_stats=NCAABTeamStats.objects.prefetch_related('name').filter(name__name__in=teams_playing).order_by(sort)
you can learn more on prefetch_related Here
I am using the below lines to pass data to my template index.html, model1 being the class in my models.py.
data = model1.objects.all()
return TemplateResponse(request, 'index.html', {'data': data})
I am able to access data on the front end by using a for loop as shown below
{% for x in data %}
<h3>{{x.name}}</h3>
<h4>{{x.department}}</h4>
{% endfor %}
Since there are mutliple objects in this data, my question is if I want to access only the department of particular object with certain name, how can I do that?
For example here I am using a for loop, consider there are two objects in the data. Then the output would be
name1
department1
name2
department2
So now if I need to access only name2 without any loop, how can i do that?
Updating the question: I am updating this question with html, so that the question looks clear.
table id="example" class="table table-striped" cellspacing="1" width="100%">
<thead>
<tr>
<th>ID</th>
<th>Name</th>
<th>Department</th>
<th>View/Edit</th>
</tr>
</thead>
<tbody>
{% for x in data %}
<tr>
<td>{{x.id}}</td>
<td>{{x.name}}</td>
<td>{{x.department}}</td>
<td>View</td>
<button type="button" class="btn-sm btn-primary btn-lg" data-toggle="modal" data-target="#myModal">
view</button></td>
</tr>
{% endfor %}
</tbody>
This is how my html looks, I am using data-table here. So all the data is captured in a table automatically. As you can see every row has a view button that I would implement. Once the user clicks the view button, I should pop up a modal dialog to show all the other details like {{x.dateJoined}} etc which I don't show in the table. But if I use a separate view to pop this dialog, I should send a request to the view from my template saying which row(with some ID) the user has clicked. How can i achieve that? How can I bind the view button with respective rows here?
You need to write custom template tag which will take the queryset and filtering parameters and returns you appropriate object, you can use simple_tag:
myapp/templatetags/myapp_tags.py
from django import template
register = template.Library()
#register.simple_tag
def get_model1_object(queryset, **filters):
if not filters:
raise template.TemplateSyntaxError('`get_model1_object` tag requires filters.')
retrun queryset.filter(**filters).first()
Then in template:
{% load get_model1_object from myapp_tags %}
{% get_model1_object data name='blah' as obj %}
Note: Your filtering criteria might yield multiple results but in get_model1_object i am only returning the first object assuming your criteria will be strict, change it according to your needs.
The first thing to understand is that template rendering happens on the server, before the user sees anything in their browser. The template is not sent to the user, only the HTML that the template generated. When the user is interacting with the page, the original template is not involved. So, you have two choices here:
You can render the data for all the objects in hidden div's on your page, then use javascript with something like a jquery dialog to display them on demand. This is only realistic if you have very few records.
You can create a second view with its own template, which renders just the HTML for the modal dialog contents. You could then, again using javascript/jquery, make an AJAX request to load the contents of the dialog that you need when you need it. In your first view template, the list of departments, include the url of the object you want to fetch, eg:
{% for x in data %}
<tr>
<td>{{x.name}}</td>
<td><a class="deptlink" href="{% url 'dept_detail' x.pk %}">
{{ x.department }}</a></td>
</tr>
{% endfor %}
Where dept_detail is the name of the urls.py entry for your view that supplies the contents of the dialog.
Then in your javascript, hook the a tag so it opens your dialog instead of leaving the page:
$('.deptlink').click(function (event) {
event.preventDefault();
# then the code after this is up to you, but something that'll
# load the url into your dialog and open it.
$('yourdialog').load($(event.target).attr('href'));
Since you say you are an intermediate in javascript I won't get into the details of implementation, but basically, the moral of the story is that the output of django is going to be an HTML page. Anything that you need to have on the client side either has to be in that page, or you will have to make another request to the server to get it... Either way, you'll need some javascript to do this, since you want a modal dialog with client side interaction.
I will try my best to be as concise as possible.
In my back end, I have a list of dictionaries saved to a variable. Each dictionary represents a post from reddit and includes the score, url, and title.
Respectively, the template will loop through this list and then return the values of each of these keys to the user like so:
<table>
<tr>
{% for x in data[0:5] %}
<td>
{{ x['score'] }}
{{ x['title'] }}
<br>
<a href='/add_to_favorites'> Add To Favorites </a>
</td>
{% endfor %}
</tr>
</table>
As you can see, there's an tag which is linked to a function on my utils.py that is attempting to save the respective dictionary to the database (I have a model that represents the url, title, and score).
I feel as though my template is not representing the dictionary in the correct way, for my link to include the html as when it is pressed I receive a 404 error (though I have this route already defined in views.py - '/add_to_favorites' which calls my 'save_post' function).
def save_post():
data = get_info()
for post in data:
fav= Favorite(title=post.get('title'), url=post.get('url'), score=post.get('score'), user_id=current_user.id)
db.session.add(fav)
db.session.commit()
return redirect(url_for('favorites'))
and:
#app.route('/add_to_favorites')
#login_required
def add_to_favorites():
return save_post()
Am i going about this the wrong way? How can i make sure that the link/button is associated with only the html of the that it is included in?
Just need some guidance into the right direction here, not necessarily the code to fix it. Thank you
Following is the simple database model i have:
class Notes(db.Model):
text = db.StringProperty(multiline=True)
date = db.DateTimeProperty(auto_now_add=True)
Now in the url handler, i send all the notes to the template as follows:
class MainPage(webapp2.RequestHandler):
def get(self):
notes = Notes.all()
self.render_template("index.html", {'notes':notes})
In the template i am using jinja2 templating engine, i want the id of each of the notes to be printed, so that i can embed an edit link, somewhat like this:
{% for note in notes %}
<p>
{{ note.text }} <br>
{{ note.date }} <br>
(edit )
{% endfor %}
But the trouble is, i dont see anything printed, in place of note.key.id
As per the docs over here key class represents a unique key for a database entity and this has a method id, its a numeric value. for a single note from the collection of notes i want the id of the note.
If i use the django templating engine i get the values {{ notes.key.id }} printed, but with jinja2 i dont see it.
How can i do this?
Well replace the href line with the following:
(edit )
This shall be enough.