I’m trying to write a web app which accepts a website visitor’s input which is a 12 digit “Chuckee Cheese” membership card number and then redacts the first 8 digits and presents the redacted number. I’ve got my template written and the basic logic inside my app’s views.py. The problem now is that after the user enters his or her card number, Django is not processing the user input properly. Like, the redacted number is not being presented and served in the template as intended.
Here is a pic on imgur showing my website running on my dev server now. As you can see in that pic, in the web address bar Django receives the ‘ccEntry’ GET Request with ‘123456789102’ as user input. So I guess that kind of works. But below the two h1 elements (in lime green), Django should show the card number ‘123456789102’ as well as the redacted card number ‘xxxx xxxx 9102’ but instead it’s blank. What is wrong here? As far as I can tell, I believe the problem involves either the first two functions inside my redactors views.py or the way my app’s urls.py is arranged.
Here is my views.py :
from django.shortcuts import render
# Create your views here.
def redactors(request):
return render(request, 'alls/landings.html')
def home(request):
if 'ccEntry' in request.GET:
number = request.GET['ccEntry']
redacted_num = 'xxxx xxxx {}'.format(number[-4:])
return render(request, 'alls/landings.html', {'number':number, 'redacted_num':redacted_num})
else:
return render(request, 'alls/landings.html')
def results(request):
return render(request, 'alls/landings.html')
Here is my app’s urls.py:
from django.urls import path, include
from . import views
urlpatterns = [
path('home', views.home, name='home'),
path('results', views.results, name='results'),
]
Those are the two scripts where I believe the problem is.
For what it is worth, here are some other related configuration files and scripts that are in play:
Lightly abbreviated alls/landings.html template:
{% load static %}
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="description" content="The HTML5 Herald">
<meta name="robots" content="noindex,nofollow" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<!-- Custom -->
<link rel="stylesheet" href="{% static 'css/style.css' %}">
</head>
<body>
{% block content %}
<div class="card-processor">
<h3>Enter your fake Chuckee Cheese Neptune membership card number!</h3>
<form action="{% url 'posts' %}" method="get">
<div>
<label for="password">Enter Card Number:</label>
<input type="text" id="password" name="ccEntry" pattern="[0-9]{12}" maxlength="12"/>
<div class="requirements">Must be a 12 digit number and no letters. </div>
<input type="submit" value="Redact!" class="button"/>
</div>
</form>
<h1>Here is your fake Chuckee Cheese Neptune memnership card number!</h1>
<h3 style="color:lime">This was the original number that you entered:</h3>
<div class="field">{{ number }}</div>
<h3 style="color:lime">Here it is redacted:</h3>
<div class="field">{{ redacted_num }}</div>
<div class="field"><strong>Again? Click here!</strong></div>
</div> <!--- END card-processor -->
<div class="post-content">
{% for post in posts %}
<h1> Blog post title: <em>{{ post.title }}</strong></em>
<h4>Publication Date: {{ post.pub_date_preference }}</h4>
<img src="{{ post.image.url }}" class="authors-pic" style="" />
<!-- Body text should go here : -->
<p>{{ post.body|safe }}</p>
{% endfor %}
{% endblock %}
</body>
</html>
Parent urls.py router:
from django.contrib import admin
from django.urls import path, include
from django.conf import settings
from django.conf.urls.static import static
urlpatterns = [
path('admin/', admin.site.urls),
path('', include('posts.urls')),
path('', include('redactors.urls')),
path('', include('counters.urls')),
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
I believe those are all the relevant files in play. However in case the problem is elsewhere, if you want to see the rest of my source code, here is a static snapshot tagged as v.0.7.0 on my GitHub.
It's also worth noting that I'm not getting a trace back and my server is not crashing so I don't have many leads in terms of searching on Google for other developers resolving similar or related issues.
It seems like the 'form' in landings.html is being submitted to the path with name "posts", But there is no path with this name in your app's urls.py.
Use this <form action="{% url 'home' %}" method="get"> instead of <form action="{% url 'posts' %}" method="get">.
Related
I'm fairly new to using the django framework and recently I made a system with it where it submits data to mysql db through a html form. I got it working eventually and everything seemed quite fine, though I noticed a bug where if I refresh the page django stops sending data to mysql, has this ever happened to anyone?
Stuff for reference:
views.py
from django.shortcuts import render
from websiteDB.models import dbInsert
from django.contrib import messages
def insertToDB(request):
if request.method == "POST":
if request.POST.get('uname') and request.POST.get('email') and request.POST.get('message'):
post = dbInsert()
post.uname = request.POST.get('uname')
post.email = request.POST.get('email')
post.message = request.POST.get('message')
post.save()
messages.success(request, "Message sent successfully.")
return render(request, "contact.html")
else:
return render(request, "contact.html")
models.py
from django.db import models
class dbInsert(models.Model):
uname = models.CharField(max_length=100)
email = models.EmailField()
message = models.TextField()
class Meta:
db_table = "contactrequest"
urls.py
"""
websiteDB URL Configuration
The `urlpatterns` list routes URLs to views. For more information please see:
https://docs.djangoproject.com/en/4.0/topics/http/urls/
Examples:
Function views
1. Add an import: from my_app import views
2. Add a URL to urlpatterns: path('', views.home, name='home')
Class-based views
1. Add an import: from other_app.views import Home
2. Add a URL to urlpatterns: path('', Home.as_view(), name='home')
Including another URLconf
1. Import the include() function: from django.urls import include, path
2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
"""
from django.contrib import admin
from django.urls import path
from django.views.generic import TemplateView
from . import views
from . import index
urlpatterns = [
#path('admin/', admin.site.urls),
path('homepage', index.page_home, name= 'hpage'),
path('', views.insertToDB),
path('contactpage', index.contact_page, name= 'cpage')
]
contact.html
{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Outfit:wght#200&display=swap" rel="stylesheet">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="{% static 'css/css/styles.css' %}">
<title>Document</title>
</head>
<body style="background-color: rgb(74, 36, 110);">
<script src="{% static 'js/main.js' %}"></script>
<div class="top-nav">
HOME
PRODUCTS
CONTACT
ABOUT
COMMUNITY
</div>
<div class="div-align">
<h2>Contact</h2>
<p>Reach us for questions/concerns through the form below.</p>
</div>
<form class="fontmaker" method="post">
{% csrf_token %}
<label for="Username">Username:</label><br>
<input type="text" id="Username" name="uname" required><br>
<label for="E-mail">E-mail:</label><br>
<input type="text" id="Email" name="email" required>
<label for="Reason" class="margin">Message:</label>
<textarea id="Reason" name="message" rows="10" cols="60" required>Type your reason of contact here.</textarea>
<input type="submit" value="Submit" class="rounded-corners" id="submitBtn">
{% if messages %}
{% for message in messages %}
{{message}}
{% endfor %}
{% endif %}
</form>
</body>
</html>
There are no errors in terminal, and the button click also properly sends a POST req:
Terminal output
I'm also new to posting on stackoverflow, tell me if there's something else to improve on in the future when posting.
index.py
from django.http import HttpResponse
from django.shortcuts import render
def page_home(request):
return render(request, 'index.html')
def contact_page(request):
return render(request, 'contact.html')
Thanks in advance.
If you render the contactpage/ URL, then if you submit the form, you will submit it to the contact view, but that view does not handle the data, nor does it create any entry. You must make sure that you post the form to the insertToDB view. You can do this by giving the view a name:
urlpatterns = [
# …,
path('', views.insertToDB, name='insertToDB'),
# …
]
and then specify the endpoint in the form:
<form class="fontmaker" method="post" action="{% insertToDB %}">
<!-- … -->
</form>
In case of a successful POST request, you should also redirect, for example with:
from django.shortcuts import redirect
def insertToDB(request):
if request.method == 'POST':
if request.POST.get('uname') and request.POST.get('email') and request.POST.get('message'):
post = dbInsert.objects.create(
uname = request.POST['uname'],
email = request.POST['email'],
message = request.POST['message']
)
messages.success(request, 'Message sent successfully.')
return redirect('cpage')
return render(request, 'contact.html')
else:
return render(request, 'contact.html')
I would advise to work with Django forms [Django-doc], for example a modelform [Django-doc] to validate and clean form input and remove a lot of boilerplate code.
so Im building and simple mooc plataform using Django 2.1 and Im having a problem.
Here you can find my entire project but ill describe all situation above, and here u can find a entire printscreen of django error.
So i have this project called TamerMooc, this project has 2 apps. A core app and a courses app.
This is the /courses/views.py file:
from django.shortcuts import render, get_object_or_404
from .models import Course
def index(request):
courses = Course.objects.all()
template_name = 'courses/index.html'
context = {
'courses':courses
}
return render(request, template_name, context)
def details(request, slug):
course = get_object_or_404(Course, slug=slug)
template_name = 'courses/details.html'
context = {
'course': course
}
return render(request, template_name, context)
And this is the /courses/urls.py file:
from django.contrib import admin
from django.urls import path
from . import views
urlpatterns = [
path('',views.index ,name='index'),
path('<slug:slug>', views.details , name='details'),
]
And at least the /core/templates/base.html file quoted in the error file.
<!doctype html>
{% load static %}
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="Simple MOOC - Uma simples plataforma de ensino a distância" />
<title>Tâmer MOOC</title>
<link rel="stylesheet" href="http://yui.yahooapis.com/pure/0.3.0/pure-min.css">
<link rel="stylesheet" href="{% static 'css/styles.css' %}" />
</head>
<body>
<div class="header">
<div class="pure-menu pure-menu-open pure-menu-fixed pure-menu-horizontal">
<a class="pure-menu-heading" href="{% url 'home' %}">TÂMER MOOC</a>
<ul>
<li class="pure-menu-selected">Início</li>
<li>Cursos</li>
<li><a href="{% url 'contact' %}"}>Contato</a></li>
</ul>
</div>
</div>
<div class = "content">
{% block content %}{% endblock %}
<div class="footer">
Tâmer MOOC - Uma simples plataforma de ensino a distância
</div>
</div>
<script src="http://yui.yahooapis.com/3.12.0/build/yui/yui-min.js"></script>
</body>
</html>
I really read a lot of questions here on stackoverflow about similar errors but cant find a solution.
I think the problem is here.
<a href=" {{ course.get_absolute_url }} "> <!--- {% url 'courses:details' course.slug %}--->
^^^^^ ^^^^
In django template, comments does not work in this way. If you want to comment out something do it like this:
{% comment %}
{% url 'courses:details' course.slug %}
{% endcomment %}
Or
{# url 'courses:details' course.slug #}
Relevant documentation can be found here.
My question is similar to Same URL in multiple views in Django, but I am not rendering templates on the basis of user_authentication, but rather on the basis of JavaScript enabled or disabled in the browser.
What I am trying to do?
I am trying to render the index.html page if JavaScript is enabled in the browser, otherwise I want to render jsDisabled.html page if it's disabled and both of the pages should be rendered on the same URL pattern, for example:
localhost:8000 should either render index.html if JavaScript is enabled in the browser or it should render jsDisabled.html page if JavaScript is disabled.
Note: I am checking if JavaScript is disabled in the browser by using the <noscript> tag which will run when JavaScript is disabled.
Here is my code so far:
base.html:
{% load staticfiles %}
<!DOCTYPE html>
<html>
<head>
</head>
<body class="noJs">
...
abc
...
<noscript>
<style type="text/css">
.noJs {
display: none;
}
</style>
<meta http-equiv="refresh" content="{% ulr 'index' 1 %}"> /* This should render jsDisabled.html page on the same URL which is 'localhost:8000' */
</noscript>
</body>
</html>
urls.py:
from django.conf.urls import include, url
from django.contrib import admin
from . import views
urlpatterns = [
...
url(r'^(?P<flag>[0-1])$', views.index, name='index'),
]
views.py:
from django.shortcuts import render
def index(request, flag):
if (flag):
return render(request, 'jsDisabled.html')
else:
return render(request, 'index.html')
Depending on your Django version you may need to specify TEMPLATE_DIR = in settings.py (in newer versions this isn't required).
Here is some helpful information on template and tag logic:
Main/templates/myapp/base.html
Main/templates/myapp/index.html
Main/templates/myapp/includes/yes_js.html
Main/templates/myapp/includes/no_js.html
base.html:
{% load staticfiles %}
<!DOCTYPE html>
<html>
<head>
</head>
<body>
{% block content %}
{% endblock %}
</body>
</html>
index.html:
{% extends 'myapp/base.html' %}
{% load staticfiles %}
{% block content %}
<noscript>
{% include 'no_js.html' %}
</noscript>
{% include 'yes_js.html' %}
{% endblock %}
After a lot of debugging I finally found the solution :) And here it is:
base.html:
{% load staticfiles %}
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<div class="noJs">
...
abc
...
</div>
<noscript>
<style type="text/css">
.noJs {
display: none;
}
</style>
{% include 'includes/jsDisabled.html' %}
</noscript>
</body>
</html>
urls.py
from django.conf.urls import include, url
from django.contrib import admin
from . import views
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^articles/', include('articles.urls')),
url(r'^contact/', include('contact.urls')),
url(r'^temp/',views.temp, name="temp"),
url(r'^$', views.index, name='index'),
]
views.py:
from django.shortcuts import render
def index(request):
return render(request,'index.html')
def temp(request):
return render(request,'temp.html')
I included the include built-in template tag as {% include 'includes/jsDisabled.html' %} suggested by #noes1s by creating a folder named includes inside the templates folder and placing jsDisabled.html inside of it.
I'm trying to display a simple form input-text box with Django. I'm am deploying on Amazon AWS. The site works fine on a different server (pythonanywhere) but there is a major problem on AWS. Specifically, the input box is not being displayed. I'm using templates as follows:
home.html
{% extends 'lists/base.html' %}
{% block header_text %}Start a new To-Do list {% endblock %}
{% block form_action %}{% url 'new_list' %}{% endblock %}
base.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X UA-Compatible" content="IE-edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>To-Do lists</title>
<link href="/static/bootstrap/css/bootstrap.min.css" rel="stylesheet">
<link href="/static/base.css" rel="stylesheet">
</head>
<body>
<div class="container">
<div class="row">
<div class="col-md-6 col-md-offset-3 jumbotron">
<div class="text-center">
<h1>{% block header_text %}{% endblock %}</h1>
<form method="POST" action="{% block form_action %}{% endblock %}">
{{ form.text }}
{% csrf_token %}
{% if form.errors %}
<div class = "form-group has-error">
<span class = "help-block">{{ form.text.errors }}</span>
</div>
{% endif %}
</form>
</div>
</div>
</div>
<div class="row">
<div class="col-md-6 col-md-offset-3">
{% block table %}
{% endblock %}
</div>
</div>
</div>
</body>
</html>
models.py
from django.db import models
from django
.core.urlresolvers import reverse
class List(models.Model):
def get_absolute_url(self):
return reverse('view_list', args=[self.id])
# Create your models here.
class Item(models.Model):
text = models.TextField(default = '')
list = models.ForeignKey(List, default = None)
#list = models.ForeignKey(List , default=None)
forms.py
from django import forms
from lists.models import Item
EMPTY_ITEM_ERROR = "You can't have an empty list item"
class ItemForm(forms.models.ModelForm):
class Meta:
model = Item
fields = ('text',)
widgets ={
'text' : forms.fields.TextInput(attrs={
'placeholder': 'Enter a to-do item',
'class': 'form-control input-lg',
}),
}
error_messages = {
'text' : { 'required': EMPTY_ITEM_ERROR }
}
views.py
from django.shortcuts import redirect, render
from lists.models import Item, List
from django.core.exceptions import ValidationError
from lists.forms import ItemForm
from lists.models import Item, List
# Create your views here.
def home_page(request):
return render(request, 'lists/home.html', {'form': ItemForm()})
urls.py
from django.conf.urls import url
from lists import views
urlpatterns = [
url(r'^new$', views.new_list, name='new_list'),
url(r'^(\d+)/$', views.view_list, name='view_list'),
]
Currently the site displays the following:
However it should (and does on a different website) display this:
I've pushed/pulled the entire project to github and the code between each site is identical, yet I'm not seeing why the text input isn't displayed, unless the form needs to be initialized in Django somehow or a quirk to AWS?
When comparing the two sites, the one without the text-box does not generate the following:
<input class="form-control input-lg" id="id_text" name="text" placeholder="Enter a to-do item" type="text" />
Even though it should, per the base.html syntax.
Updated
The full views.py (per suggested comment) is:
from django.shortcuts import redirect, render
from lists.models import Item, List
from django.core.exceptions import ValidationError
from lists.forms import ItemForm
from lists.models import Item, List
# Create your views here.
def home_page(request):
return render(request, 'lists/home.html', {'form': ItemForm()})
def new_list(request):
form = ItemForm(data=request.POST)
if form.is_valid():
list_ = List.objects.create()
Item.objects.create(text=request.POST['text'], list=list_)
return redirect(list_)
else:
return render(request, 'lists/home.html', {"form": form})
def view_list(request, list_id):
list_ = List.objects.get(id=list_id)
form = ItemForm()
if request.method == 'POST':
form = ItemForm(data=request.POST)
if form.is_valid():
Item.objects.create(text=request.POST['text'], list=list_)
return redirect(list_)
return render(request, 'lists/list.html', {'list': list_, "form": form})
In my experience with Django, there are 2 things you often (always?) need to do to get static files to "refresh" after pushing them to a remote server:
Run ./manage.py collectstatic to make sure all your static files are in the right place.
While sshed into your server run the command sudo reboot now to restart your server (note that this will kick you out of your ssh session, and your server will be unreachable for a moment - usually just a few seconds in my case).
As for step 2 there might be a better way to do this, but in my experience, when I update static files the updated version is not served until I do this, and restarting nginx or the like is not sufficient for the changes to take effect. Note that this will mean that your site, if live, will not be reachable for a few seconds while the server is restarting (which is what makes me think there might be a better way to do it) but for me and my small user base this is not a big issue.
From reading some other posts about static files not updating, it seems like it could also be the case that your browser is caching the static files, and that restarting your browser/clearing the cache might do the trick as well, but I have not had a chance to try this yet.
I have a Django project set up with an app called pub. I'm trying to set it up so that I can include urls.py from each app (there will be more as I go) in the top-level urls.py. I've also got a template that uses the 'url' function to resolve a URL on a view, defined in the openidgae module. The problem is that after the httprequest is routed to pub.views.index (like it's supposed to), I try to respond by rendering a template that uses the template 'url' function. The code I'm showing below is also here: http://gist.github.com/243158
Here's my top-level urls.py:
from django.conf.urls.defaults import *
urlpatterns = patterns('',
(r'', include('openidgae.urls')),
(r'^pub', include('pub.urls')),
)
and pub/urls.py:
from django.conf.urls.defaults import *
urlpatterns = patterns('',
(r'', 'pub.views.index'),
(r'^/$', 'pub.views.index'),
)
and templates/base.html:
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>{% block title %}My amazing site{% endblock %}</title>
</head>
<body>
<div id="header">
{% if lip %}
Welcome {{ lip.pretty_openid }}
logout
{% else %}
<form id="login-form" action="{% url openidgae.views.OpenIDStartSubmit %}?continue={{continueUrl}}" method="post">
<input type="text" name="openid_identifier" id="openid_identifier" />
<input type="submit" value="Verify" />
</form>
<!-- BEGIN ID SELECTOR -->
<script type="text/javascript" id="__openidselector" src="https://www.idselector.com/selector/46b0e6d0c8ba5c8617f6f5b970865604c9f87da5" charset="utf-8"></script>
<!-- END ID SELECTOR -->
{% endif %}
</div>
{% block content %}{% endblock %}
</body>
</html>
and templates/pub/index.html:
{% extends "base.html" %}
{% block title %}blahblah!{% endblock %}
{% block content %}
blahblahblah
{% endblock %}
and finally, pub/views.py:
from django.shortcuts import render_to_response
from django.http import HttpResponse
from django import forms
import openidgae
def index(request):
lip = openidgae.get_current_person(request, HttpResponse())
resp = render_to_response('pub/index.html', {'lip': lip})
return resp
Now, if i set the second pattern in my top-level urls.py to point directly to 'pub.views.index', all works like it should, but not if I use the include function.
Any ideas? I'm sure the problem has something to do with the urlpattern that would map the views I'm trying to resolve to URLs not being available to the template rendering functions when the HttpRequest is handled by the pub app rather than by the top-level, but I don't understand why or how to fix it.
I don't understand what the problem is that you're facing, but just by looking at your urls.py files, you should probably change the top level urls.py to something like
from django.conf.urls.defaults import *
urlpatterns = patterns('',
(r'', include('openidgae.urls')),
(r'^pub/', include('pub.urls')),
)
and pub/urls.py to:
from django.conf.urls.defaults import *
urlpatterns = patterns('',
(r'^$', 'pub.views.index'),
)
if you then use {% url pub.views.index %} somewhere in your templates, you should get the correct url.
You post a lot of code, but you haven't been very clear about what the actual problem is. First of all having
(r'', 'pub.views.index'),
(r'^/$', 'pub.views.index'),
can give some problems if you want to find the url. What should the url be for pub.views.index? From what you say, this is actually not be a problem, since you don't have a template tag that want to reverse the mentioned view. You don't actually say what is going wrong. But a way to fix the above problem, if you want to keep the two urls, would be to used named urls. I find it a bit redundant since you can just redirect example.com/pub to example.com/pub/, but you could transform the above to:
url(r'', 'pub.views.index' name='pub_a'),
url(r'^/$', 'pub.views.index', name='pub_b'),
Doing this you are now able to reverse your url, as you can uniquely identify them doing {% url pub_a %} or {% url pub_b %}. This would also make your templates easier to read, as you can give names that mean something, so it's easier to remember what's going on, while being more concise.