FLASK, Requested URL not found on the server - python

ISSUE
I am making a CRUD in Flask. I have a user that has positions, and I would like to update a specific position.
The "URL was not found" problem occurs when I click on the anchor link in user_positions.html.
I am using WTF Forms, SQLalchemy, PostgreSQL, Bootstrap, and pgAdmin4.
I hope I have given you enough information.
The requested URL was not found on the server. If you entered the URL manually please check your spelling and try again.
http://0.0.0.0:5000/user/24/url_for('user_position_update',%20owner_id=current_user.id,%20position_id=position.id)%20%7D%7D
MY CODE
user_positions.html
<i class="mdi mdi-pencil"></i> Update
routes.py
#app.route("/user/<string:owner_id>/positions/<string:position_id>/update", methods=['GET', 'POST'])
def user_position_update(owner_id, position_id):
user = User.query.filter_by(id=owner_id).first()
position = Position.query.filter_by(id=position_id).first()
form = UpdatePositionForm()
if current_user.is_authenticated:
if form.validate_on_submit():
strSQl= "update position set position='"+position+"' where owner_id="+str(user.id)
db.session.execute(strSQl)
db.session.commit()
flash('Your position has been updated!', 'success')
return redirect(url_for('user_positions'))
elif request.method == 'GET':
form.position.data = position
return render_template('user_position_update.html', form=form, user=user, position=position)
forms.py
class UpdatePositionForm(FlaskForm):
position = StringField('Position',
validators=[DataRequired()])
date = DateTimeField('Date',
validators=[DataRequired()])
submit = SubmitField('Update')
user_position_update.html
{% extends "layout.html" %}
{% block content %}
<table class="table">
<tr>
<th>Position</th>
<th>Date</th>
</tr>
<tr>
<form method="POST" enctype="multipart/form-data">
{{ form.hidden_tag() }}
<td>
<div class="form-group">
{{ form.positions.label(class="form-control-label") }}
<select class="form-control form-control-sm" name="position">
<option>{{ current_user.positions[-1].position }}</option>
<option>1</option>
<option>2</option>
<option>3</option>
<option>4</option>
<option>5</option>
<option>6</option>
<option>7</option>
<option>8</option>
<option>9</option>
<option>10</option>
<option>11</option>
<option>12</option>
<option>13</option>
<option>14</option>
<option>15</option>
</select>
</div>
</td>
<td>
<div class="form-group">
{{ form.position.label(class="form-control-label") }}
<input type="date" class="form-control" value="{{ position.created_date }}" name="date">
</div>
</td>
<td>
<div class="form-group">
{{ form.submit(class="btn btn-outline-info") }}
</div>
</td>
</tr>
</table>
{% endblock content %}
PostgreSQL tables
user table
position table

Related

Python Django Edit HTML rows and update database

I have a table and I wish to add an edit button that updates the certain record both visually and in the database.
The HTML I have.
{% for work_entry in work_entries %}
{% if work_entry.date == date.date %}
<form action="{% url 'work_entries:object_edit' work_entry.id %}" method="post">
{% csrf_token %}
<tr>
<td>
<button onclick="return confirm('Are you sure you want this edit?')">Edit
</button>
</td>
<td> <form action="{% url 'work_entries:object_delete' work_entry.id %}" method="post">
{% csrf_token %}
<button onclick="return confirm('Are you sure you want to delete this record?')">Delete
</button>
</form>
</td>
<td>{{ work_entry.id }}</td>
<td><input type="text" value="{{ work_entry.description }}" name="description"></td>
<td><input type="number" value="{{ work_entry.num_hours }}" name="hours"></td>
</tr>
</form>
{% endif %}
{% endfor %}
The views.py
def object_edit(request, object_id):
record = get_object_or_404(WorkEntry, pk=object_id)
if request.method == "POST":
record.description = request.POST["description"]
record.num_hours = request.POST["hours"]
record.save()
return redirect("/employeePage")
return render(request, "employeePage.html")
And urls.py
app_name = "work_entries"
urlpatterns = [
path("", views.employee_view, name="employeePage"),
url(r"^delete/(?P<object_id>[0-9]+)/$", views.object_delete, name="object_delete"),
url(r"^edit/(?P<object_id>[0-9]+)/$", views.object_edit, name="object_edit"),
]
I used an input tag in the as I thought that would allow me to change data and save it. However this is giving me MultiValueDictKeyError at /employeePage/edit/14/
'description' error. I am not too experienced with jquery which from research I saw that could work but I don't seem to get it right. Can someone help or even suggestions on how I should approach this would be useful.
Note: there is already a button to delete the record which works, I tried a similar approach for editing, but it doesn't work.
I fully encourage you to use the forms provided by Django, it will make your life easier.
And I fully encourage you as well to not use a form for your delete stuff, it should be a simple link, it would avoid to have a form in a form. I think your problem is here. Having a form in a form with the button in the middle make impossible for your browser to know which parts of the form you want to submit.
As well you have two buttons but none of them is submit type.
If you don't want to use the Django forms a way to do it would be
{% for work_entry in work_entries %}
{% if work_entry.date == date.date %}
<form action="{% url 'work_entries:object_edit' work_entry.id %}" method="post">
{% csrf_token %}
<tr>
<td>
<button>
Delete
</button>
</td>
<td> <button type="submit" onclick="return confirm('Are you sure you want to update this record?')">
Update
</button>
</td>
<td>{{ work_entry.id }}</td>
<td><input type="text" value="{{ work_entry.description }}" name="description"></td>
<td><input type="number" value="{{ work_entry.num_hours }}" name="hours"></td>
</tr>
</form>
{% endif %}
{% endfor %}
It's not the most beautiful way to do it I tried to keep your achitecture

How To Populate Table With Filtered Data in Django

I am attempting to populate a table with a filtered set of data from my Manifests model using a url parameter.
I believe that the problem I am having is in the Views.py line
manifests = Manifests.objects.all().filter(reference=reference_id)
Models.py
class Manifests(models.Model):
reference = models.ForeignKey(Orders)
cases = models.IntegerField()
description = models.CharField(max_length=1000)
count = models.IntegerField()
def __str__(self):
return self.description
Urls.py
url(r'^add_manifest/(?P<reference_id>\d+)/$', add_manifest, name='add_manifest'),
Views.py
def add_manifest(request, reference_id):
if request.method == "POST":
form = CreateManifestForm(request.POST)
if form.is_valid():
instance = form.save(commit=False)
try:
order = Orders.objects.get(id=reference_id)
except Orders.DoesNotExist:
pass
instance.reference = order
instance.save()
return redirect('add_manifest', reference_id=reference_id)
form = CreateManifestForm()
#manifests = Manifests.objects.all()
manifests = Manifests.objects.all().filter(reference=reference_id)
context = {
'form': form,
'reference_id': reference_id,
'manifests' : manifests,
}
return render(request, 'add_manifest.html', context)
template (add_manifest.html)
{% extends 'base.html' %}
{% block body %}
<div class="container">
<form method="POST">
<br>
<br>
<br>
{% csrf_token %}
<div class="column">
<label for="form.reference">Reference ID: </label><br>
<input type="text" value="{{ reference_id }}">
<br>
</div>
<div class="description">
<div class="column">
<label for="form.description">Description: </label>
<br>
{{ form.description}}
</div>
</div>
<div class="column">
<label for="form.cases">Cases: </label>
<br>
{{ form.cases }}
<br>
</div>
<div class="column">
<label for="form.count">Count: </label>
<br>
{{ form.count }}
<br>
<br>
</div>
<br>
<br>
<button type="submit" name="add_mani" style="border-color: #7395AE;">Add Line</button>
</form>
<br>
<h4>Manifest</h4>
<div class="table-responsive">
<table class="table table-striped table-bordered manifest_table" cellspacing="0" style="width="100%">
<thead>
<tr>
<th></th>
<th style="width:10%;">Ref ID</th>
<th style="width:10%;">Cases</th>
<th style="width:60%;">Description</th>
<th style="width:10%;">Count</th>
</tr>
</thead>
<tbody>
{% for manifests in manifests %}
<tr>
<td>
Edit
</td>
<td>{{ manifests.reference }}</td>
<td>{{ manifests.cases }}</td>
<td>{{ manifests.description}}</td>
<td>{{ manifests.count}}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
<div class="text-center">
<button type="submit" class="btn btn-primary" name="button" align="right">Subit Manifest</button>
</div>
</div>
I want the table to display only lines where the reference in the Manifests model = the reference_id in the URL. Currently it does not work as such, the table is just empty.
Change the for-loop variable name like this:
{% for manifest in manifests %}
<tr>
<td>
Edit
</td>
<td>{{ manifest.reference }}</td>
<td>{{ manifest.cases }}</td>
<td>{{ manifest.description}}</td>
<td>{{ manifest.count}}</td>
</tr>
{% endfor %}
If there is any Manifest object for reference_id, then it will render them in template.
Update
Its possible that your form is not validating. So its a good idea to render form errors:
# view
def add_manifest(request, reference_id):
form = CreateManifestForm(request.POST or None)
if request.method == "POST":
if form.is_valid():
instance = form.save(commit=False)
try:
order = Orders.objects.get(id=reference_id)
instance.reference = order
except Orders.DoesNotExist:
pass
instance.save()
manifests = Manifests.objects.all().filter(reference=reference_id)
context = {
'form': form,
'reference_id': reference_id,
'manifests' : manifests,
}
return render(request, 'add_manifest.html', context)
And update template to show the errors in template as well:
{% if form.errors %}
{% for field in form %}
{% for error in field.errors %}
<div>
<strong>{{ error|escape }}</strong>
</div>
{% endfor %}
{% endfor %}
{% for error in form.non_field_errors %}
<div>
<strong>{{ error|escape }}</strong>
</div>
{% endfor %}
{% endif %}

How to customize login in django

I have a registration page for teachers having fields like email, mobile number, password etc, the table is named as Teacher.
I want to login page too for the same.
What I am doing is:
Added following in url page:
url(r'^login/$', auth_views.login, {'template_name': 'login.html'},name='login'),
Added following in settings.py:
AUTH_USER_MODEL = 'myapp.Teacher'
Added login.html:
{% extends "base.html" %}
{% load widget_tweaks %}
{% block body_block %}
{% if form.errors %}
<p>Your username and password didn't match. Please try again.</p>
{% endif %}
{% if next %}
{% if user.is_authenticated %}
<p>Your account doesn't have access to this page. To proceed,
please login with an account that has access.</p>
{% else %}
<p>Please login to see this page.</p>
{% endif %}
{% endif %}
<div class="container">
<div class="row">
<div class="col-md-4 col-md-offset-4">
<div class="login-panel panel panel-default">
<div class="panel-heading">
<h3 class="panel-title">Please Sign In</h3>
</div>
<div class="panel-body">
<form method="post" action="{% url 'login' %}">
{% csrf_token %}
<p class="bs-component">
<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>
</p>
<p class="bs-component">
<center>
<input class="btn btn-success btn-sm" type="submit" value="login" />
</center>
</p>
<input type="hidden" name="next" value="{{ next }}" />
</form>
</div>
</div>
</div>
</div>
</div>
{%endblock body_block%}
Now the login page doesn't work, giving me error:
AttributeError: type object 'Teacher' has no attribute 'REQUIRED_FIELDS'
How can I implement custom login page in django?

MultiValueDictKeyError while updating inline formsets

I'm having an issue with Django while updating inline formsets. I want to update a form and an inline formset, but it raises this error:
"MultiValueDictKeyError"
Exception Value: "u'clientphone_set-0-id'"
This is my view:
def edit_client(request, client_id):
client_to_edit = Client.objects.get(id=client_id)
form = ClientForm(instance=client_to_edit)
phone_formset = ClientPhoneFormSet(instance=client_to_edit)
if request.method == 'POST':
form = ClientForm(request.POST, instance=client_to_edit)
if form.is_valid():
form_saved = form.save(commit=False)
phone_formset = ClientPhoneFormSet(request.POST, request.FILES, instance=form_saved)
if phone_formset.is_valid():
form_saved.save()
phone_formset.save()
return client(request)
return render(request, 'WorkOrders/add_client.html', {'form' : form, 'phone_formset' : phone_formset})
And these are my forms
class ClientForm(forms.ModelForm):
name = forms.CharField(max_length=128)
rif = forms.CharField(max_length=10)
address = forms.CharField(max_length=250)
class Meta:
model = Client
fields = ('name','rif','address',)
ClientPhoneFormSet = inlineformset_factory(Client, ClientPhone, extra=1, fields=('phone_number',), can_delete=True)
And this is my template
<form class="form-horizontal" id="add_client" method="post" action=".">
{% csrf_token %}
{% for field in form.visible_fields %}
<div class="form-group">
<label for="{{ field.id }}" class="col-sm-2 control-label">{{ field.help_text }}</label>
<div class="col-sm-10">
{{ field.errors }}
{{ field }}
</div>
</div>
{% endfor %}
<div class="form-group">
<label for="{{ field.id }}" class="col-sm-2 control-label">Teléfono</label>
<div class="col-sm-10">
<table border="0" cellpadding="0" cellspacing="0" width="100%">
<tbody>
{% for form in phone_formset.forms %}
<tr>
<td>
{% if form.instance.pk %}
{{ form.DELETE }}
{% endif %}
{{ form.errors }}
{{ form.phone_number }}
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
{{ phone_formset.management_form }}
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<button type="submit" class="btn btn-primary">Guardar</button>
Volver
</div>
</div>
</div>
</form>
It opens the form with no problem, the error happens when I submit.
Thanks.
I fixed it by using phone_formset instead of phone_formset.forms, and added the {{ phone_field.id }}.
Here is the result:
<table border="0" cellpadding="0" cellspacing="0" width="100%">
<tbody>
{% for phone_field in phone_formset %}
<tr>
<td>
{% if phone_field.instance.pk %}
{{ phone_field.DELETE }}
{% endif %}
{{ phone_field.errors }}
{{ phone_field.id }}
{{ phone_field.phone_number }}
</td>
</tr>
{% endfor %}
</tbody>
</table>

Url not changing , just render the template after login

The URL is not changing and data is not fetching after user login.
After Login the url not changed(i expected to change to 127.0.0.1:8000/employer/home)
#login_required
def home(request):
emp=Employer.objects.get(user=request.user)
jb=Job.objects.filter(employer=emp).order_by("-postdate")
return render(request,'employer/home.html',{'jobs':jb})#,{'employer':emp})
employer/home.html
<table class="table table-hover table-bordered">
<tr><th>Job ID</th><th>Title</th><th>Posted on</th></tr>
{% for job in jobs %}
<tr>
<td>{{ job.pk }}</td>
<td>{{ job.title }}</td>
<td>{{ job.postdate }}</td>
</tr>
{% endfor %}
</table>
login.html
<form class="form-signin" action="" method="post">{% csrf_token %}
<h4 class="form-signin-heading">Sign in to my account...</h4>
{% if errors %}
<p class="text-error">Sorry, that's not a valid username or password</p>
{% endif %}
<input type="text" id="username" class="input-block-level" name="username" placeholder="UserID">
<input type="password" id="password" class="input-block-level" name="password" placeholder="Password">
<p style="text-align:right;">Forgot your password?</p>
<button class="btn btn-large btn-success" type="submit" value="login">Sign in</button>
</form>
You need to tell it where to go after login using the next url parameter:
<form class="form-signin" action="{% url django.contrib.auth.views.login %}?next=employer/home/" method="post">
or set the LOGIN_REDIRECT_URL in settings:
The URL where requests are redirected after login when the contrib.auth.login view gets no next parameter.

Categories