Django PasswordInput is printing object instead of form field - python

I am trying to create my own authentication system by making use of Django Auth module. The problem is when I print my form in the template, Username and text field is displaying fine but the password field its displaying object something like this <django.forms.widgets.PasswordInput object at 0x00000000039E1710>
Here is my form
class UserLoginForm(forms.Form):
username = forms.CharField(required = True)
password = forms.PasswordInput(render_value = True)
And the template goes here.
{% if form.errors %}
<p>Your username and password didn't match. Please try again.</p>
{% endif %}
<form method="post" action="/portal/login">
{% csrf_token %}
<table>
<tr>
<td>{{ form.username.label_tag }}</td>
<td>{{ form.username }}</td>
</tr>
<tr>
<td>{{ form.password.label_tag }}</td>
<td>{{ form.password }}</td>
</tr>
</table>
<input type="submit" value="login" />
<input type="hidden" name="next" value="{{ next }}" />
</form>
Some one help me on this
-Vikram

change
password = forms.PasswordInput(render_value = True)
to
password = forms.CharField(widget=forms.PasswordInput(render_value = True))

OK, I got the answer: After correcting the form like this its displaying fine
class UserLoginForm(forms.Form):
username = forms.CharField(required = True)
password = forms.CharField(widget=forms.PasswordInput())
Sorry for the spam
-Vikram

Related

Name attribute of input field identical modelform

I am trying to loop through a Model PendingRequest and check the every request instance of a user and approve or decline the users request for each instance.I am using a ModelForm to render my form however, the part that gives issue is that the radio button to click on whether to approve or decline do not share the same input name attribue
here is my template
<form method="post">
{% csrf_token %}
<table>
<thead>
<tr>
<th>Book Title</th>
<th>Status</th>
</tr>
</thead>
<tbody>
{% for book in books %}
<tr>
<td>{{ book.book.title }}</td>
<td>
<input type="radio" name="{{ book.id }}" value="approved"> Approve
<input type="radio" name="{{ book.id }}" value="not_approved"> Decline
</td>
</tr>
{% endfor %}
</tbody>
</table>
<button type="submit">Update</button>
</form>
so what i want to achieve is to replace
<input type="radio" name="{{ book.id }}" value="approved"> and <input type="radio" name="{{ book.id }}" value="not_approved"> with this below such that when it is rendered, every loop will have same the name attribute but different values
<form method="post">
{% csrf_token %}
<table>
<thead>
<tr>
<th>Book Title</th>
<th>Status</th>
</tr>
</thead>
<tbody>
{% for book in books %}
<tr>
<td>{{ book.book.title }}</td>
<td>
{% for choice in form.approved %}
{{choice.tag}}
{% endfor %}
{% for choice in form.not_approved %}
{{choice.tag}}
{% endfor %}
</td>
</tr>
{% endfor %}
</tbody>
</table>
<button type="submit">Update</button>
</form>
here is my forms.py
class Approve(forms.ModelForm):
approved = forms.BooleanField(widget=forms.RadioSelect(choices=[(True, 'Approve')]))
not_approved = forms.BooleanField(widget=forms.RadioSelect(choices=[(True, 'Decline')]))
class Meta:
model = PendingRequest
exclude = ["member", "book_request", "book"]
models.py
class PendingRequest(models.Model):
book_request = models.OneToOneField(BorrowBook, on_delete=models.CASCADE, null=True)
member = models.ForeignKey(User, on_delete=models.CASCADE, default="", null=True)
book = models.ForeignKey(Books, on_delete=models.CASCADE, default="", null=True)
approved = models.BooleanField(default=False)
not_approved = models.BooleanField(default=False)
approval_date = models.DateTimeField(auto_now=True, null=True)
views.py
def approve(request, pk):
books = PendingRequest.objects.filter(member__id=pk)
if request.method == "POST":
for book in books:
form = Approve(request.POST, instance=book)
if form.is_valid():
book.approve = form.cleaned_data.get(f'approve_{book.id}')
book.save()
return redirect(index)
else:
form = Approve()
return render(request, "books/approve.html", {"form": form, "books": books})
You are making this a little complicated for yourself...
You have two booleans in that PendingRequest model. One for approved and one for not_approved. You only want one, because if approved is False, then it's already not_approved by definition.
You also are making life difficult by having two radio button fields with one radio button each for field. Radio buttons are for multiple choice, one value allowed. You could use two radio buttons for one field (a checkbox is often better) but having two radio buttons for two separate fields is not only bad HTML, you'll likely be able to select both at once. If you give them the same name to prevent that, they won't be linked to the correct field without a lot of weird post-POST fiddling about. It's very messy. I'd really advise using a single field.
Regardless if you take that advice, for multiple forms of the same model, Django can handle this situation with a modelformset, something like...
views.py
PendingRequestFormSet = modelformset_factory(PendingRequest , form = Approve)
#we have to also bring in the book title along with the forms , even though we are not using it in the form,
# so we'll zip up the queryset with the formset.
# We use select_related in the queryset to prevent additional database calls in the template when the title gets evaluated
pending_requests = PendingRequest.objects.filter(member__id=pk).select_related('book')
formset = PendingRequestFormSet(queryset=pending_requests))
pending_requests_and_formset = zip(queryset, formset)
...
return render(request, "books/approve.html", {"form": form, "books": books, 'pending_requests_and_formset', pending_requests_and_formset })
template.html
...
<form method="post">
{{ formset.management_form }}
{% for request, form in pending_requests_and_formset %}
<td>{{request.book.title}}</td>
<td>{{ form }}</td>
{% endfor %}
</form>

Modify data cell of table with condition in Jinja

I have made a page that shows a table with two columns: Users and their Points.
I want to make bold the data cell that has the name of the User session. The table is made in a Jinja for loop. So I created a .bold class in CSS and a condition inside the loop. But it doesn't work at all.
I am very new at code so I am sorry if my question is very simple. Thanks in advance.
I think this is the relevant part of my index.
if request.method == 'GET':
user = session['user_id']
userN = db.execute("SELECT username FROM users WHERE id=?", user)
username = userN[0]["username"]
return render_template('index.html', fixtures=fixtures, username=username, homeScore=homeScore, awayScore=awayScore, userScore=userScore, userHome=userHome, userAway=userAway, usuarios=usuarios)
My HTML:
{% for user in usuarios %}
<tr>
{% if user["username"] == "{{ username }}" %}
<td class="bold">{{ user["username"] }}</td>
{% else %}
<td>{{ user["username"] }}</td>
{% endif %}
<td>{{ user["puntos"] }}</td>
</tr>
{% endfor %}
</tbody>
Thank you all for your answers.
It finally worked!
I followed the advice of RodrigoCava and Maiels and got it. It was an issue with the database query and also I was putting {{ }} where I shouldn't.
This is the final code:
def index():
if request.method == 'GET':
user = session['user_id']
usern = db.execute("SELECT username FROM users WHERE id=?", user)
username = usern[0]["username"]
And the HTML
{% for user in usuarios %}
<tr>
{% if user["username"] == username %}
<td class="bold">{{ user["username"] }}</td>
{% else %}
<td>{{ user["username"] }}</td>
{% endif %}
<td>{{ user["puntos"] }}</td>

Pass information from html form to python flask

I am new to flask and web applications, trying to create a web application that takes the name and the sport for each user and store it in sqlite DB, now Iam trying to remove users from the DB by taking the registrant id from the html to flask.
flask:
#app.route("/deregister")
def deregister():
value_from_html = ?????
db.excute("DELETE * FROM registrant WHERE id = ?", value_from_html)
html:
{% extends "layout.html" %}
{% block body %}
<h1>Registrant name</h1>
<tbody>
{% for registrant in registrants %}
<tr>
<td>{{ registrant.name }}</td>
<td>{{ registrant.sport }}</td>
<td>
<form action="/deregister" method="post">
<input name="id" type="hidden" value="{{ registrant.id }}"> !-- trying to pass registrant.id to flask --!
<input type="submit" value="Deregister">
</form>
</td>
</tr>
{% endfor %}
</tbody>
{% endblock %}
python code is not complete yet.
You can recieve the form data in the following way.
#app.route("/deregister", methods=['POST'])
#login_required
def deregister():
try:
if request.method == 'POST':
if request.files:
uploaded_file = request.files['filename']
data = uploaded_file.stream.read()
In order to send a variable to flask, you dont need to use forms, you can easily do that in the following way,
#app.route("/deregister/<string:id>", methods=['POST'])
#login_required
def deregister(id):
try:
variable = id
print(variable)
In html, keep this,
{% extends "layout.html" %}
{% block body %}
<h1>Registrant name</h1>
<tbody>
{% for registrant in registrants %}
<tr>
<td>{{ registrant.name }}</td>
<td>{{ registrant.sport }}</td>
<td>
<a href='/deregister/{{ registration.id }}'>Send Id</a>
</td>
</tr>
{% endfor %}
</tbody>
{% endblock %}
After trying to solve it my self finaly Ive found a way to do that:
1)Add button in my html to remove from DB:
I hope that this will help any one as it did for me.

I am having errors with CS50 Finance problem in registration process

The error is ":( registering user succeeds" and ":( registration rejects duplicate username"
The detailed error log mentions that there is no table such as 'stock found'
Other registration processes have green ticks.
Can someone please help out with this code?
Here is my registration code in application.py
#app.route("/register", methods=["GET", "POST"])
def register():
"""Register user"""
# Forget any user_id
session.clear()
# User reached route via POST (as by submitting a form via POST)
if request.method == "POST":
# Ensure username was submitted
if not request.form.get("username"):
return apology("Oh dear, give us the username!")
# Ensure password was submitted
elif not request.form.get("password"):
return apology("You have to give us password!")
elif not request.form.get("confirmation"):
return apology("You have to confirm your password!")
# Ensure confirm password is correct
elif request.form.get("password") != request.form.get("confirmation"):
return apology("Oops, your passwords don't match up!")
# Insert user and hash of the password into the table
newuser = db.execute("INSERT INTO users (username, hash) VALUES (:username, :hash)",
username=request.form.get("username"),
hash=generate_password_hash(request.form.get("password")))
if not newuser:
return apology("Someone else swiped right on this Username, try a new one!")
# Query database for username
rows = db.execute("SELECT * FROM users WHERE username = :username",
username=request.form.get("username"))
# Remember which user has logged in
session["user_id"] = rows[0]["id"]
# Redirect user to home page
return redirect(url_for("index"))
# User reached route via GET (as by clicking a link or via redirect)
else:
return render_template("register.html")
I have also given below the index code below - for the error with 'stock' table
#app.route("/")
#login_required
def index():
"""Show portfolio of stocks"""
# Query infos from database
rows = db.execute("SELECT * FROM stocks WHERE user_id = :user",
user=session["user_id"])
cash = db.execute("SELECT cash FROM users WHERE id = :user",
user=session["user_id"])[0]['cash']
# pass a list of lists to the template page, template is going to iterate it to extract the data into a table
total = cash
stocks = []
for index, row in enumerate(rows):
stock_info = lookup(row['symbol'])
# create a list with all the info about the stock and append it to a list of every stock owned by the user
stocks.append(list((stock_info['symbol'], stock_info['name'], row['amount'], stock_info['price'], round(stock_info['price'] * row['amount'], 2))))
total += stocks[index][4]
return render_template("index.html", stocks=stocks, cash=round(cash, 2), total=round(total, 2))
HTML for register
{% extends "layout.html" %}
{% block title %}
Register
{% endblock %}
{% block main %}
<form action="/register" method="post">
<fieldset>
<div class="form-group">
<input autocomplete="off" autofocus class="form-control" name="username" placeholder="Username" type="text">
</div>
<div class="form-group">
<input class="form-control" name="password" placeholder="Password" type="password">
</div>
<div class="form-group">
<input class="form-control" name="confirmation" placeholder="Confirm password" type="password">
</div>
<button class="btn btn-primary" type="submit">Register</button>
</fieldset>
</form>
{% endblock %}
HTML for Index
{% extends "layout.html" %}
{% block title %}
Stocks
{% endblock %}
{% block main %}
<table class="table">
<thead class="thead-light">
<tr>
<th scope="col">Symbol</th>
<th scope="col">Name</th>
<th scope="col">Shares</th>
<th scope="col">Price</th>
<th scope="col">Total</th>
</tr>
</thead>
<tbody>
{% for stock in stocks %}
<tr>
<th scope="row">{{ stock[0] }}</th>
<td>{{ stock[1] }}</td>
<td>{{ stock[2] }}</td>
<td>{{ stock[3] }}</td>
<td>{{ stock[4] }}</td>
</tr>
{% endfor %}
<tr>
<th scope="row">Cash</th>
<td></td>
<td></td>
<td></td>
<td>{{ cash }}</td>
</tr>
<tr>
<th scope="row"></th>
<td></td>
<td></td>
<td></td>
<td>{{ total }}</td>
</tr>
</tbody>
</table>
{% endblock %}
Before Insert user and hash of the password into the table, do SELECT on the request.form.get("username"), to see if the username already exists. Then if something is returned, return an error message. I think that should solve the problem.

Wring file retrieved using Blobstore

I have form upload and handler which allows download uploaded files from blobstore.
The problem is when I click Download button of any related-field it downloads the same file every time. I.e. I've uploaded 3 files (1.txt, 2.txt, 3.txt) and it always downloads only 1.txt whenever I clicked another Download buttons. You can see it at http://my77notes.appspot.com/show (or http://my77notes.appspot.com/upload first for uploading your own files).
When I've researched source code it shows me different keys for every hidden fields..
What did I wrong?
Here is my files:
template file:
<h2>Files uploaded to Blobstore</h2>
<table border="3">
<tr>
<td>#</td>
<td>Filename</td>
<td>Content-Type</td>
<td>Creation</td>
<td>Size</td>
<td>Download</td>
</tr>
<form id="show_blob" name="show_blob" method="post" action="{{ download_blob }}">
{% for file in blob_files %}
<tr>
<td>{{ loop.index }}</td>
<td>{{ file.filename }}</td>
<td>{{ file.content_type }}</td>
<td>{{ file.creation }}</td>
<td>{{ file.size }}</td>
<td>
<input type="submit" name="download" value="Download"/>
<input type="hidden" name="blobkey" value="{{ file.key() }}" />
</td>
</tr>
{% endfor %}
</form>
</table>
handler.py
class BlobstoreServeHandler(RequestHandler, BlobstoreDownloadMixin):
def post(self):
blob_info = blobstore.BlobInfo.get(self.request.form.get('blobkey'))
return self.send_blob(blob_info, save_as=True)
urls.py
rules = [
Rule('/', endpoint='index', handler='apps.77notes.handlers.IndexPageHandler'),
Rule('/upload', endpoint='upload/html', handler = 'apps.77notes.handlers.BlobstoreUploadFormHandler'),
Rule('/upload/handler', endpoint='upload/handler', handler='apps.77notes.handlers.UploadHandler'),
Rule('/download', endpoint='download/html', handler = 'apps.77notes.handlers.BlobstoreDownloadFormHandler'),
Rule('/download/file', endpoint='download/file', handler='apps.77notes.handlers.BlobstoreServeHandler'),
Rule('/show', endpoint='show/html', handler='apps.77notes.handlers.ShowUploadedFilesHandler'),
]
variables
blob_files = uploaded_files_to_blobstore = blobstore.BlobInfo.all()
download_blob = self.url_for('download/file')
Thanks!
Of course it's always the first. You're declaring three hidden fields with the same name but various values. How could the server understand you want “the hidden field nearest to the download button I clicked”?
You could do this with Javascript but it's overkill. Maybe you should rather create forms for each item, but I'm not sure it is HTML-valid.
{% for file in blob_files %}
<tr>
<!-- stuff -->
<td><form class="show_blob" name="show_blob" method="post" action="{{ download_blob }}">
<input type="submit" name="download" value="Download" />
<input type="hidden" name="blobkey" value="{{ file.key() }}" />
</form></td>
</tr>
{% endfor %}
If you don't like this, you could also provide the index of the desired blobkey within the download submit button. Something like this:
{% for file in blob_files %}
<tr>
<!-- stuff -->
<td>
<input type="submit" name="dl{{ loop.counter0 }}" value="Download" />
<input type="hidden" name="blobkey" value="{{ file.key() }}" />
</td>
</tr>
{% endfor %}
Then, server-side, you get the right blobkey using:
# don't forget to handle errors here, NTUI
ind = int([_[2:] for _ in self.request.form if _.startswith('dl')][0])
blobkeys = self.request.form.getlist('blobkey')
blobkey = blobkeys[ind]
# stuff
if you what to download through form you need to do as many form as blob you have
{% for file in blob_files %}
<tr>
<td>{{ loop.index }}</td>
<td>{{ file.filename }}</td>
<td>{{ file.content_type }}</td>
<td>{{ file.creation }}</td>
<td>{{ file.size }}</td>
<td>
<form id="show_blob" name="show_blob" method="post" action="{{ download_blob }}">
<input type="submit" name="download" value="Download"/>
<input type="hidden" name="blobkey" value="{{ file.key() }}" />
</form>
</td>
</tr>
{% endfor %}
or you can do it by ordinary A tag like this <a href = '/get/{{ file.key() }}'>

Categories