Appengine - how to get an entity and display values - python

I'm having trouble with my project. I have 2 models
class UserPrefs(db.Model):
user = db.UserProperty()
name = db.StringProperty()
class Person(db.Model):
name = db.StringProperty()
phone = db.PhoneNumberProperty()
userPrefs = db.ReferenceProperty(UserPrefs)
class PersonHandler(webapp.RequestHandler):
def get(self):
users.get_current_user user = ()
if user:
greeting = ......
else:
greeting = ......
if self.request.GET.has_key ('id'):
id = int (self.request.get ['id'])
person = models.Person.get = (db.Key.from_path ('Person', id))
path = os.path.join (os.path.dirname (__file__), 'templates / doStuff.html')
self.response.out.write (template.render (path, locals (), debug = True))
def post (self):
if self.request.get ('Person'):
id = int (self.request.get ('Person'))
person = models.Person.get (db.Key.from_path ('Person', id))
else:
person= models.Person = ()
data = forms.PersonForm date = (data = self.request.POST)
if data.is_valid ():
if self.request.get ('photo'):
Person.foto db.Blob = (self.request.get ('photo'))
person.nome self.request.get = ('name')
person.apelido self.request.get = ('name')
person.unidade self.request.get = ('unit')
person.put ()
self.redirect ('/ doSomeStuff')
else:
self.redirect ('doOtherStuff')
To See the data in database i use this handler:
class SeePersonHandler (webapp.RequestHandler):
def get (self):
users.get_current_user user = ()
if user:
greeting = ......
else:
greeting = ......
person= db.Query(models.Pocente)
persons = person.fetch(limit = 1)
path = os.path.join(os.path.dirname(__file__), 'templates/SeeStuff.html')
self.response.out.write(template.render(path, locals(), debug = True))
Question:
I knows that the data is put corectly. I used the SDK Console with this url: http://localhost:8080/_ah/admin/datastore and the entity is created correctly. I donĀ“t know what i am missing to retrieve the dadta already put
My Template:
{% if user %}
{% if person%}
<table align="center">
<tbody>
<tr>
<td><input type="button" value="Criar Pessoa" onclick="redirect(3)" /></td>
</tr>
</tbody>
</table>
<table align="center">
<tbody>
<tr>
<td colspan="2"><center><strong><p>O meu Curriculum Vitae</p></strong></center></td>
</tr>
<tr>
<td>Nome: </td>
<td>{{ person.name}}</td>
</tr>
<tr>
<td>Apelido: </td>
<td>{{ person.phone}}</td>
</tr>
<tr>
<td></td>
<td>
<input type ="button" value="Editar" onclick="editarCv({{ person.key.id }})" />
</td>
</tr>
</tbody>
</table>
{% endif %}
{% endif %}

Your code is a bit disorganised.
Debugging is generally easier with better-organised code.
Anyway, enough of the trash-talking.
You're assigning the result of a datastore query to persons...
persons = person.fetch(limit = 1)
...but then in your template you use person:
<tr>
<td>Nome: </td>
<td>{{ person.name}}</td>
</tr>
<tr>
<td>Apelido: </td>
<td>{{ person.phone}}</td>
</tr>
It is difficult to tell if this is your only problem (I highly doubt it), but perhaps you can try fixing that and get back to us. Best of luck to you.
Aside: instead of .fetch(limit=1) you can simply use .get() as mentioned in the documentation:
get() implies a "limit" of 1. At most
1 result is fetched from the
datastore.

Related

.objects.all() returns nothing

its my first time to ask hope I can find solution to my problem. Am trying to display the courses in an html page using objects.all() but it returns nothing and the page remain empty, even though records do exist in the database. I tried the same method for other pages and it worked, idk what am doing wrong here :(
in view.py
def viewCourse(request):
corlist = Course.objects.all()
#print(muffin)
#course.count()
context = {'corlist':corlist}
return render(request, 'LogInApp/ViewCourse.html', context)
in model.py
class Course(models.Model):
COURSES = (
('Data Structure','Data Structure'),
('Computer Network','Computer Network'),
('Web Design','Web Design'),
('Internet of Things','Internet of Things'),
('Artificial Intelligence','Artificial Intelligence'),
('Artificial Intelligence-Tut', 'Artificial Intelligence-Tut'),
)
course_id = models.AutoField(primary_key=True)
course_name = models.CharField(max_length=100, null=True, choices= COURSES)
fk_lecturer_id = models.OneToOneField(Lecturer, on_delete=models.CASCADE) # foreign key
date = models.DateField(max_length=20, null=True)
time = models.TimeField(max_length=20, null=True)
def __str__(self):
return '{} {}'.format(self.course_id, self.course_name)
#property
def lecturerid(self):
return self.fk_lecturer_id.lecturerid
in ViewCourse.html
<table border="1" class="table">
<tr>
<th>Course ID</th>
<th>Course Name</th>
<th>Course Lecturer</th>
<th>Date</th>
<th>Time</th>
<th width="100px"> </th>
</tr>
{% for co in corlist %}
<tr>
<td> {{ co.course_id }} </td>
<td> {{ co.course_name }} </td>
<td> {{ co.fk_lecturer_id }} </td>
<td> {{ co.date }} </td>
<td> {{ co.time }} </td>
</tr>
{% endfor %}
</table>

Render HTML Table with Editable WTForms FieldList and Non-Editable Values Using Jinja2 Flask

I'm using Flask and Jinja2 and I need to make an attendance table that includes both editable and non-editable fields. I referred to other posts such as here and here which got me to this point. The table successfully displays the editable fields using FieldList. However, I have not been able to render the non-editable fields.
This is what the table should look like:
The only fields which should be editable are "attendance code" and "comment". Unfortunately, I have not found a way to include the other fields (class name, start time, end time, first name, last name) as simple text fields.
I have tried using the read-only attribute for WTForms. While this is functional, it displays the text in text boxes which don't look appealing.
My latest attempt shown below defines a WTForms class called updateStudentAttendanceForm that inherits the fields from another class called attendanceLogClass that includes instance variables for the desired fields. I assign the values to the form class in the routes.py file. However, when I reference these variables in the html file, they result in blank fields. I have used a print statement to verify the variable assignments are working properly. I cannot figure out why the variables do not display properly when included in the html template.
forms.py
class attendanceLogClass:
def __init__(self):
self.classAttendanceLogId = int()
self.className = str()
self.firstName = str()
self.lastName = str()
self.startTime = datetime()
self.endTime = datetime()
def __repr__(self):
return f"attendanceLogClass('{self.classAttendanceLogId}','{self.className}','{self.firstName}','{self.lastName}','{self.startTime}','{self.endTime}')"
class updateStudentAttendanceForm(FlaskForm, attendanceLogClass):
attendanceCode = RadioField(
"Attendance Code",
choices=[("P", "P"), ("T", "T"), ("E", "E"), ("U", "U"), ("Q", "?"),],
)
comment = StringField("Comment")
submit = SubmitField("Submit Attendance")
class updateClassAttendanceForm(FlaskForm):
title = StringField("title")
classMembers = FieldList(FormField(updateStudentAttendanceForm))
routes.py
#app.route("/classattendancelog")
def displayClassAttendanceLog():
classAttendanceForm = updateClassAttendanceForm()
classAttendanceForm.title.data = "My class"
for studentAttendance in ClassAttendanceLog.query.all():
studentAttendanceForm = updateStudentAttendanceForm()
studentAttendanceForm.className = studentAttendance.ClassSchedule.className
studentAttendanceForm.classAttendanceLogId = studentAttendance.id
studentAttendanceForm.className = studentAttendance.ClassSchedule.className
studentAttendanceForm.startTime = studentAttendance.ClassSchedule.startTime
studentAttendanceForm.endTime = studentAttendance.ClassSchedule.endTime
studentAttendanceForm.firstName = (
studentAttendance.ClassSchedule.Student.firstName
)
studentAttendanceForm.lastName = (
studentAttendance.ClassSchedule.Student.lastName
)
studentAttendanceForm.attendanceCode = studentAttendance.attendanceCode
studentAttendanceForm.comment = studentAttendance.comment
# The following print statement verified that all of the variables are properly defined based on the values retrieved from the database query
print(studentAttendanceForm)
classAttendanceForm.classMembers.append_entry(studentAttendanceForm)
return render_template(
"classattendancelog.html",
title="Class Attendance Log",
classAttendanceForm=classAttendanceForm,
)
classattendancelog.html:
{% extends 'layout.html'%}
{% block content %}
<h1> Class Attendance </h1>
<form method="POST" action="" enctype="multipart/form-data">
{{ classAttendanceForm.hidden_tag() }}
<table class="table table-sm table-hover">
<thead class="thead-light">
<tr>
<th scope="col">Class Name</th>
<th scope="col">Start Time</th>
<th scope="col">End Time</th>
<th scope="col">First Name</th>
<th scope="col">Last Name</th>
<th scope="col">Attendance Code</th>
<th scope="col">Comment</th>
</tr>
</thead>
<tbody>
{% for studentAttendanceForm in classAttendanceForm.classMembers %}
<tr>
<td> {{ studentAttendanceForm.className }}</td>
<td> {{ studentAttendanceForm.startTime }}</td>
<td> {{ studentAttendanceForm.endTime }}</td>
<td> {{ studentAttendanceForm.firstName }}</td>
<td> {{ studentAttendanceForm.lastName }} </td>
<td>
{% for subfield in studentAttendanceForm.attendanceCode %}
{{ subfield }}
{{ subfield.label }}
{% endfor %}
</td>
<td>
{{ studentAttendanceForm.comment(class="form-control form-control-sm") }}
</td>
</tr>
{% endfor %}
</tbody>
</table>
{% endblock content %}
Note: I haven't yet written the code to handle the form response.
I solved the problem by using the zip function to iterate simultaneously through two lists: one list with the FormField data and a second list with the non-editable "fixed field" data.
To use "zip" in the HTML template, I followed the instructions here and added this line to my init.py
app.jinja_env.globals.update(zip=zip)
updated forms.py (eliminated attendanceLogClass with fixed field variables):
class updateStudentAttendanceForm(FlaskForm):
attendanceCode = RadioField(
"Attendance Code",
choices=[("P", "P"), ("T", "T"), ("E", "E"), ("U", "U"), ("Q", "?"),],
)
comment = StringField("Comment")
submit = SubmitField("Submit Attendance")
class updateClassAttendanceForm(FlaskForm):
title = StringField("title")
classMembers = FieldList(FormField(updateStudentAttendanceForm))
updated routes.py (added new variable for fixed fields called classAttendanceFixedFields):
#app.route("/classattendancelog")
def displayClassAttendanceLog():
classAttendanceFixedFields = ClassAttendanceLog.query.all()
classAttendanceForm = updateClassAttendanceForm()
classAttendanceForm.title.data = "My class"
for studentAttendance in ClassAttendanceLog.query.all():
studentAttendanceForm = updateStudentAttendanceForm()
studentAttendanceForm.attendanceCode = studentAttendance.attendanceCode
studentAttendanceForm.comment = studentAttendance.comment
classAttendanceForm.classMembers.append_entry(studentAttendanceForm)
return render_template(
"classattendancelog.html",
title="Class Attendance Log",
classAttendanceForm=classAttendanceForm,
classAttendanceFixedFields=classAttendanceFixedFields,
)
updated classattendancelog.html (incorporated zip function in the for loop to simultaneously iterate through the editable fields and fixed fields).
{% extends 'layout.html'%}
{% block content %}
<h1> Class Attendance </h1>
<form method="POST" action="" enctype="multipart/form-data">
{{ classAttendanceForm.hidden_tag() }}
<table class="table table-sm table-hover">
<thead class="thead-light">
<tr>
<th scope="col">Class Name</th>
<th scope="col">Start Time</th>
<th scope="col">End Time</th>
<th scope="col">First Name</th>
<th scope="col">Last Name</th>
<th scope="col">Attendance Code</th>
<th scope="col">Comment</th>
</tr>
</thead>
<tbody>
{% for studentAttendanceForm, studentFixedFields in zip(classAttendanceForm.classMembers, classAttendanceFixedFields) %}
<tr>
<td> {{ studentFixedFields.ClassSchedule.className }}</td>
<td> {{ studentFixedFields.ClassSchedule.startTime.strftime('%-I:%M') }}</td>
<td> {{ studentFixedFields.ClassSchedule.endTime.strftime('%-I:%M') }}</td>
<td> {{ studentFixedFields.ClassSchedule.Student.firstName }}</td>
<td> {{ studentFixedFields.ClassSchedule.Student.lastName }} </td>
<td>
{% for subfield in studentAttendanceForm.attendanceCode %}
{{ subfield }}
{{ subfield.label }}
{% endfor %}
</td>
<td>
{{ studentAttendanceForm.comment(class="form-control form-control-sm") }}
</td>
</tr>
{% endfor %}
</tbody>
</table>
{% endblock content %}

Get value/state of checkbox for each row in a Django when POST

I want to display a table with :
on rows: the date for each weekday (calculate in my views.py)
on columns: the Mealselection of an user.
I can get value from models and display it :
https://i.imgur.com/TyvI0DH.png
But when i look source code on the page i see https://i.imgur.com/wY0QC62l.png
So obviously it does not work when i try to save the user choice because it will update only one date, today for exemple, since there are the same form id i think.
I try with a formset but i can't pass initial value to the template "selection_template.html" (i try with the exemple below but don't work because i need to display the user selection in relation with date of weekday.
formset = ArticleFormSet(initial=[{'title': "Form %d" % (i+1),
'pub_date': datetime.date.today()} for i in range(10)])
I know how to display multi form using formset but don't know how to pass value to the template.
models.py
class MealSelection(models.Model):
user = models.ForeignKey('User', on_delete=models.CASCADE)
date = models.DateField(auto_now_add=True)
salad = models.BooleanField(default=False)
meal = models.BooleanField(default=False)
sandwich = models.BooleanField(default=False)
forms.py
class GetUserMeal(forms.ModelForm):
class Meta:
model = MealSelection
fields = ['meal', 'salad', 'sandwich']
widget = forms.CheckboxInput(
attrs={
'name': 'choices'
}
)
views.py
for day in weekDay:
try:
userSelection = MealSelection.objects.get(user=u1,date=startWeek + datetime.timedelta(days=daysCount))
userSelection = {'meal':userSelection.meal, 'salad':userSelection.salad, 'sandwich':userSelection.sandwich}
except:
userSelection = {'meal':False, 'salad':False, 'sandwich':False}
userSelection = forms.GetUserMeal(userSelection)
dateDayCorresp[day] = {'date':startWeek + datetime.timedelta(days=daysCount),'userSelection': userSelection}
daysCount += 1
selection_template.html
<form method="post">
<table class="table table-hover table-bordered vertical-align">
<thead>
<tr class="table-primary">
<th rowspan="2">Jour</th>
<th colspan="3">Repas</th>
</tr>
<tr class="table-success">
<th scope="col">Repas</th>
<th scope="col">Salade</th>
<th scope="col">Sandwich</th>
</tr>
</thead>
<tbody>
{% csrf_token %}
{% for day in dateDayCorresp.items %}
<tr>
<th scope="row" class="table-warning">
{{day.0}} ({{day.1.date}})
<!-- {{day.1.userSelection}} -->
</th>
{% for field in day.1.userSelection %}
<td>
<label>{{ field }}</label>
</td>
{% endfor %}
</tr>
{% endfor %}
</table>
<button type="submit" class="btn btn-primary btn-lg btn-block fixed-bottom" id="buttonSave">Save</button>
</form>

Loop through items into Django 1.8 template

I have this method:
def profile(request):
parsedData = []
if request.method == 'POST':
username = request.POST.get('user')
req = requests.get('https://api.github.com/users/' + username + '/repos')
jsonList = []
jsonList=req.json()
userData = {}
for data in jsonList:
userData['html_url'] = data['html_url']
userData['created_at'] = data['created_at']
userData['updated_at'] = data['updated_at']
userData['forks_count'] = data['forks_count']
parsedData.append(userData)
return render(request, 'app/profile.html', {'data': parsedData})
This code looks into an url like this githubtraining
As You can see, the response contains lots of repositories, however, not every github user has more than 1 repo.
Anyways, on my html view I have this:
<div class="table-responsive">
<table class="table table-bordered table-hover table-striped tablesorter">
<thead>
<tr>
<th class="header"> Url <i class="icon-sort"></i></th>
<th class="header"> Created at <i class="icon-sort"></i></th>
<th class="header"> Updated at <i class="icon-sort"></i></th>
<th class="header"> Forks count <i class="icon-sort"></i></th>
</tr>
</thead>
<tbody>
{% for key in data %}
<tr>
<td>{{ key.html_url }}</td>
<td>{{ key.created_at }}</td>
<td>{{ key.updated_at }}</td>
<td>{{ key.forks_count }}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
What happens then? Well, right now, if, for instance, I query the githubtraining user to see it's repos, it shows only the last one, on that and every other user, so, what am I doing wrong here? The loop is there, what am I missing?
You append data only after forloop is finished inside your view. You need to append it after each iteration instead:
for data in jsonList:
userData = {}
userData['html_url'] = data['html_url']
userData['created_at'] = data['created_at']
userData['updated_at'] = data['updated_at']
userData['forks_count'] = data['forks_count']
parsedData.append(userData)
With your current code:
userData = {}
for data in jsonList:
userData['html_url'] = data['html_url']
userData['created_at'] = data['created_at']
userData['updated_at'] = data['updated_at']
userData['forks_count'] = data['forks_count']
parsedData.append(userData)
new userData overrides previous one inside for cycle. And when cycle finishing you have only one record in the list.

Blank screen error on google app engine

I am trying out this idea where there is a table of 'events' on a '/search' page and when a 'GO' button of an event is pressed, it will increment the 'RSVP' count of that event, and redirect back to '/search'. However, when I clicked on the 'GO' button in my application, it leads to a blank screen with url 'localhost:8080/rsvp'.
Finding it strange and wondering which part of my code is wrong. Here are some of the relevant parts of the code that I think is causing the error.
This is the code from the python file:
class RSVPItem(webapp2.RequestHandler):
# increment RSVP count when GO button is clicked
def post(self):
itemkey = ndb.Key('Items', self.request.get('itemid'))
item = itemkey.get()
item.rsvp = item.rsvp + 1
item.put()
self.redirect('/search')
# Handler for the Search page
class Search(webapp2.RequestHandler):
# Display search page
def get(self):
user = users.get_current_user()
if user: # signed in already
# Retrieve items
query = ndb.gql("SELECT * "
"FROM Items ")
template_values = {
'user_mail': users.get_current_user().email(),
'logout': users.create_logout_url(self.request.host_url),
'items': query,
}
template = jinja_environment.get_template('search.html')
self.response.out.write(template.render(template_values))
else:
self.redirect(self.request.host_url)
app = webapp2.WSGIApplication([('/', MainPage),
('/giftbook', MainPageUser),
('/wishlist', WishList),
('/deleteitem', DeleteItem),
('/search', Search),
('/rsvp', RSVPItem),
('/display', Display),
('/displaytag', Displaytag)],
debug=True)
This is from the html file for 'search.html'. Only showing the part I think is relevant.
<h4> Events List </h4>
<table class="table table-bordered table-striped">
<thead>
<tr>
<th width="10%">Name</th>
<th>Description</th>
<th width = "10%">Link</th>
<th width = "10%">Date</th>
<th width = "10%">Type</th>
<th width = "10%">RSVP</th>
<th width = "10%">Rolling?</th>
</tr>
</thead>
<tbody>
{% for item in items %}
<tr>
<td>{{ item.event_name }} </td>
<td>{{ item.description }}</td>
<td>{{ item.event_link}}</td>
<td>{{ item.date.strftime('%Y-%m-%d') }}</td>
<td>{{ item.event_type}}</td>
<td>{{ item.rsvp }}
<td>
<form action="/rsvp" method="post">
<input type="hidden" name="itemid" value="{{ item.item_id }}">
<input type="submit" value="GO!">
</form></td>
</tr>
{% endfor %}
</tbody>
</table>
<form action="/rsvp" method="post"> sends them to /rsvp. Do you have a url handler for /rsvp?
Make sure you cast the Key to an int:
itemkey = ndb.Key('Items', int(self.request.get('itemid')))
Instead of setting your own id item_id, just use the built-in Key:
<input type="hidden" name="itemid" value="{{ item.key.id() }}">
Check the logs to see if there are any errors.

Categories