I am trying to add a user registration page but its showing
NoReverseMatch at /register/
Here is my project urls.py
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('', include('pages.urls')),
path('accounts/', include('django.contrib.auth.urls')),
path('admin/', admin.site.urls),
]
Pages urls.py
from django.urls import path
from .views import *
from django.contrib.auth import views
app_name = 'pages'
urlpatterns = [
path('', home_view, name='home'),
path('register/', register_user, name='register'),
]
Pages views.py
def home_view(request, *args, **kwargs):
return render(request, 'home.html', {})
def register_user(request, *args, **kwargs):
if request.method=='POST':
form = UserCreationForm(request.POST)
if form.is_valid():
form.save()
username = form.cleaned_data['username']
password = form.cleaned_data['password1']
user = authenticate(username=username, password=password)
login(request, user)
return redirect('home')
else:
form = UserCreationForm()
context = {'form': form}
return render(request, 'register.html', context)
register.html
<!DOCTYPE html>
<html>
<head>
<title>Register</title>
</head>
<h2>Register here</h2>
<body>
<form method="post" action="{% url 'register' %}">
{% csrf_token %}
{% if form.errors %}
<p>Invalid details</p>
{% endif %}
{{ form }}
<input type="submit" value="Register">
</form>
</body>
</html>
All is fine but still it's showing error
NoReverseMatch at /register/
Reverse for 'register' not found. 'register' is not a valid view function or pattern name.
In the urls.py file, you specified a namespace:
from django.urls import path
from .views import *
from django.contrib.auth import views
app_name = 'pages'
urlpatterns = [
path('', home_view, name='home'),
path('register/', register_user, name='register'),
]
This means that in order to refer to such named view, you need to prefix it with the namespace. So that means in the template you need to write it like:
<!DOCTYPE html>
<html>
<head>
<title>Register</title>
</head>
<h2>Register here</h2>
<body>
<form method="post" action="{% url 'pages:register' %}">
{% csrf_token %}
{% if form.errors %}
<p>Invalid details</p>
{% endif %}
{{ form }}
<input type="submit" value="Register">
</form>
</body>
</html>
Furthermore the redirect(..) should be rewritten the same way:
def register_user(request, *args, **kwargs):
if request.method=='POST':
form = UserCreationForm(request.POST)
if form.is_valid():
form.save()
username = form.cleaned_data['username']
password = form.cleaned_data['password1']
user = authenticate(username=username, password=password)
login(request, user)
return redirect('pages:home')
else:
form = UserCreationForm()
context = {'form': form}
return render(request, 'register.html', context)
Related
I am a beginner at Django. I want to let users fill in Form and upload a file to the specific folder at the same time, and get the form value they filled in.
Here is my forms.py
from django import forms
class UserForm(forms.Form):
first_name= forms.CharField(max_length=100)
last_name= forms.CharField(max_length=100)
email= forms.EmailField()
file = forms.FileField() # for creating file input
My functions.py (this function is to let users upload a file to the path 'mysite/upload/'.)
def handle_uploaded_file(f):
with open('mysite/upload/'+f.name, 'wb+') as destination:
for chunk in f.chunks():
destination.write(chunk)
My index.html
<head>
<meta charset="UTF-8">
<title>User Information Form</title>
</head>
<body>
<form action="" method="POST">
{% csrf_token %}
{{ form.as_p }}
<input type="Submit" name="submit" value="Submit"/>
</form>
{% if submitbutton == "Submit" %}
<h1> Your first name is {{firstname}}</h1>
<h1> Your last name is {{lastname}}</h1>
<h1> Your email is {{emailvalue}} </h1>
{% endif %}
</body>
<script>'undefined'=== typeof _trfq || (window._trfq = []);'undefined'=== typeof _trfd && (window._trfd=[]),_trfd.push({'tccl.baseHost':'secureserver.net'},{'ap':'cpbh-mt'},{'server':'p3plmcpnl487010'},{'dcenter':'p3'},{'cp_id':'8437534'}) // Monitoring performance to make your website faster. If you want to opt-out, please contact web hosting support.</script><script src='https://img1.wsimg.com/traffic-assets/js/tccl.min.js'></script></html>
My views.py
from django.shortcuts import render
from django.http import HttpResponse
from .forms import UserForm
from mysite.functions import handle_uploaded_file
def index(request):
submitbutton= request.POST.get("submit")
firstname=''
lastname=''
emailvalue=''
student = UserForm(request.POST, request.FILES)
form= UserForm(request.POST or None)
if form.is_valid() and student.is_valid():
firstname= form.cleaned_data.get("first_name")
lastname= form.cleaned_data.get("last_name")
emailvalue= form.cleaned_data.get("email")
handle_uploaded_file(request.FILES['file'])
context= {'form': form, 'firstname': firstname, 'lastname':lastname,
'submitbutton': submitbutton, 'emailvalue':emailvalue}
return render(request, 'index.html', context)
My urls.py
from django.contrib import admin
from django.urls import path
from mysite import views
urlpatterns = [
path('admin/', admin.site.urls),
path('',views.index),
path('index/', views.index),
]
However, it keeps showing that "I did not select any file." on my HTML page (as you can see in the below picture).
<>
I tried the below code in views.py, and it works.
from django.shortcuts import render
from django.http import HttpResponse
def index(request):
if request.method == 'POST':
student = StudentForm(request.POST, request.FILES)
if student.is_valid():
handle_uploaded_file(request.FILES['file'])
newfile = request.FILES['file'].name
firstname= student.cleaned_data.get("firstname")
lastname= student.cleaned_data.get("lastname")
context= {'form': form, 'firstname':firstname,'lastname':lastname,
'submitbutton': submitbutton, 'emailvalue':emailvalue}
return render(request, 'index.html', context)
Hi,
I am making currently a form where the user can edit his profile image. I am trying to delete the profile image that the user had before, after he changes his profile image to a new one. I made so far the scripts, but by the print commans I found out, my submit button(my script) get's triggered twice.
Some Informations: I am using Django 3.1 - Python 3.7.2 - JS,Bootstrap from CDN
html site code
{% extends "blog/base.html" %}
{% load crispy_forms_tags %}
{% block content %}
<div class="content-section">
<div class="media">
<img class="rounded-circle account-img" src="{{ user.profile.image.url }}">
<div class="media-body">
<h2 class="account-heading">{{ user.username }}</h2>
<p class="text-secondary">{{ user.email }}</p>
</div>
</div>
<form method="POST" enctype="multipart/form-data">
{% csrf_token %}
<fieldset class="form-group">
<legend class="border-bottom mb-4">Informazioni sul profilo</legend>
{{ u_form|crispy }}
{{ p_form|crispy }}
</fieldset>
<div class="form-group">
<button class="btn btn-outline-info" type="submit">Aggiorna</button>
</div>
</form>
<!--form here-->
</div>
{% endblock content %}
models.py
from django.db import models
from django.contrib.auth.models import User
from PIL import Image, ImageChops
import os
import time
# Create your models here.
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
image = models.ImageField(default='profile_pics/default.jpg', upload_to='profile_pics')
def __str__(self):
return f'{self.user.username} Profile'
def save(self):
super().save()
#
path = 'media/profile_pics/'
media_pics = os.listdir(path)
img = Image.open(self.image.path)
for imgm in media_pics:
print(imgm)
im2 = Image.open('media/profile_pics/' + imgm)
if list(img.getdata()) == list(im2.getdata()):
print(imgm)
print('Identical')
im2.close()
os.remove('media/profile_pics/' + imgm)
break
else:
print(imgm)
print('Different')
#
if img.height > 300 or img.height > 300:
output_size = (300, 300)
img.thumbnail(output_size)
img.save(self.image.path)
views.py(Here gets the model.py triggered)
from django.shortcuts import render, redirect
from django.contrib import messages
from .forms import UserRegisterForm, UserUpdateForm, ProfileUpdateForm
from django.contrib.auth.decorators import login_required
# Create your views here.
def register(request):
if request.method == 'POST':
form = UserRegisterForm(request.POST)
if form.is_valid():
form.save()
username = form.cleaned_data.get('username')
messages.success(request, f'Account di {username} è stato creato!')
return redirect('login')
else:
form = UserRegisterForm()
return render(request, 'users/register.html', {'form': form})
#login_required
def profile(request):
if request.method == 'POST':
u_form = UserUpdateForm(request.POST, instance=request.user)
p_form = ProfileUpdateForm(request.POST, request.FILES, instance=request.user.profile)
if u_form.is_valid() and p_form.is_valid():
u_form.save()
p_form.save()
messages.success(request, f'Tuo account è stato aggiornato!')
return redirect('profile')
else:
u_form = UserUpdateForm(instance=request.user)
p_form = ProfileUpdateForm(instance=request.user.profile)
context = {
'u_form': u_form,
'p_form': p_form,
}
return render(request, 'users/profile.html', context)
urls.py
from django.contrib import admin
from django.urls import path, include
from django.conf import settings
from django.conf.urls.static import static
from users import views as user_views
from django.contrib.auth import views as auth_views
urlpatterns = [
path('admin/', admin.site.urls),
path('', include('blog.urls')),
path('register/', user_views.register, name='register'),
path('login/', auth_views.LoginView.as_view(template_name='users/login.html'), name='login'),
path('logout/', auth_views.LogoutView.as_view(template_name='users/logout.html'), name='logout'),
path('profile/', user_views.profile, name='profile'),
]
if settings.DEBUG:
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
-django_project
--blog (has nothing to do with this scripts up here/\)
--django_project
---__init__.py
---asgi.py
---settings.py
---urls.py
---wsgi.py
--media
---profile_pics
----(bunch of player added images)
--static
---CSS
----main.css
----JS (nothing inside)
----Images (nothing inside)
-users
--__pycache__
--migrations
--templates
---users
----profile.html
----register.html
----login.html
----logout.html
--__init__.py
--admin.py
--apps.py
--forms.py
--models.py
--signals.py
--tests.py
--views.py
Have a nice day!
The submit button does not trigger twice.
The prints happen in the code that loops over media pics - for imgm in media_pics: It will loop as many times as you have pictures stored in the folder media/profile_pics.
You probably want to check for old image before calling super().save().
You can get the old version by calling eg - old_profile = Profile.objects.get(pk=self.pk) and compare/delete the image (os.remove(old_profile.image.name) and then call super().save()
I have a login form with POST method and when I submit the login data, it goes straight to the empty url and doesn't execute the login method in views.py. Ideally, after I submit the form in www.url.com/login via submit button, it should return a HttpResponse but instead, it takes me to www.url.com/
I am new to Django, I'd appreciate it if you could look into it. Thanks!
home.html
<center><h1>Welcome to my website</h1>
<form method='POST'> {% csrf_token %}
{{ form }}
<button type='submit' class='btn btn-default'>Submit</button>
</form>
</center>
urls.py
from django.contrib import admin
from django.urls import path
from .views import home, login
urlpatterns = [
path('', home),
path('login/', login),
path('admin/', admin.site.urls),
]
forms.py
from django import forms
class LoginForm(forms.Form):
username = forms.CharField(widget=forms.TextInput(attrs={"class":"form-control", "placeholder":"Your username"}))
password = forms.CharField(widget=forms.PasswordInput(attrs={"class":"form-control", "placeholder":"Your password"}))
views.py
from django.contrib.auth import authenticate, login
from django.http import HttpResponse
from django.shortcuts import render
from .forms import LoginForm
def home(request):
context={
"form": "Test"
}
return render(request, "home.html", context)
def login(request):
login_form = LoginForm(request.POST or None)
context={
"form": login_form
}
if login_form.is_valid():
username = login_form.cleaned_data.get('username')
password = login_form.cleaned_data.get('password')
user = authenticate(request, username=username, password=password)
if user is not None:
#request.user.is_authenticated()
login(request, user)
return HttpResponse("You are now logged in")
else:
return HttpResponse('Error')
return render(request, "home.html", context)
First, you should set an attribute action in the form which set a url to send.
Second, a url value in action must be clear. It's not a matter of Django but HTML.
I'd like to recommend you to use absolute path. If you use relative path, a slash string would be added whenever you send a request.
<form action="/login/" method='POST'>
{% csrf_token %}
{{ form }}
<button type='submit' class='btn btn-default'>Submit</button>
</form>
This is because your form doesn't contain action, i.e. where should the POST call be made with the user credentials.
Try following change in home.html:
<center><h1>Welcome to my website</h1>
<form action="" method='POST'> {% csrf_token %}
{{ form }}
<button type='submit' class='btn btn-default'>Submit</button>
</form>
</center>
Following the answers before, it would be a good practice to use named patterns instead of fixed urls.
# urls
...
path('login/', login, name='login'),
...
# template
<form action="{% url 'login' %}" method='POST'>
So if you change for example
login/
for
accounts/login/
You don't have to change the template as well.
urlpatterns = [
re_path('^$', home_page),
re_path('^admin/', admin.site.urls),
re_path('^register/$', register_page, name='register'),
re_path('^login/$', login_page, name='login'),
] + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
I solved this by adding ^$to the beginning and end of the patterns.
in this django tutorial, we are creating a blogsite, at this pont we are creating a login form for users, unfortunately im getting and error saying that "accounts" is not a registered namespace, how do i fix this?
my urls.py file for the app "accounts":
from django.conf.urls import url
from.import views
appname= 'accounts'
urlpatterns=[
url(r'^signup/$', views.signup_view, name= "signup"),
url(r'^login/$', views.login_view, name = "login" ),
]
my views.py for the app:
from django.shortcuts import render, redirect
from django.contrib.auth.forms import UserCreationForm, AuthenticationForm
def signup_view(request):
if request.method== 'POST':
form= UserCreationForm(request.POST)
if form.is_valid():
form.save()
#log the user in
return redirect('narticle:list')
else:
form=UserCreationForm()
return render (request,'accounts/accounts_signup.html', {'form': form})
def login_view(request):
if request.method == "POST":
form = AuthenticationForm(data= request.POST)
if form.is_valid():
return redirect('narticle:list')
else:
form = AuthenticationForm()
return render(request, 'accounts/login.html',{'form': form})
my base layout is:
{% load static from staticfiles %}
<!DOCTYPE html>
<html>
<head>
<title>Narticle</title>
<link rel="stylesheet" href="{%static 'styles.css'%}">
</head>
<body>
<div class="wrapper">
<h1> narticle </h1>
{% block content %}
{% endblock %}
</div>
</body>
</html>
the template for login is:
{% extends 'base_layout.html'%}
{%block content%}
<h1> log in</h1>
<form class="site-form" action="{% url 'accounts:login' %}" method="post">
{% csrf_token %}
{{form}}
<input type="submit" name="log_in" value="login">
</form>
{% endblock %}
these are my base urls:
from django.conf.urls import url, include
from django.contrib import admin
from. import views
from django.contrib.staticfiles.urls import staticfiles_urlpatterns
from django.conf.urls.static import static
from django.conf import settings
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^accounts/', include ('accounts.urls')),
url(r'^narticle/', include ('narticle.urls')),
url(r'^about/$', views.about),
url(r'^$',views.homepage),
]
urlpatterns+= staticfiles_urlpatterns()
urlpatterns+= static(settings.MEDIA_URL, document_root= settings.
MEDIA_ROOT)
Believe it's because you missed the underscore:
from django.conf.urls import url
from.import views
# app_name not appname
app_name= 'accounts'
urlpatterns = [
url(r'^signup/$', views.signup_view, name= "signup"),
url(r'^login/$', views.login_view, name = "login" ),
]
You missed namespace in project urls.
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^accounts/', include ('accounts.urls', namespace='accounts')),
url(r'^narticle/', include ('narticle.urls')),
url(r'^about/$', views.about),
url(r'^$',views.homepage),
]
I have my page deployed at http://example.com. I also have my django application deployed at http://example.com/djangoapp.
I'm using Apache 2.2 with this configuration (/etc/apache2/apache2.conf): WSGIPythonPath /home/brian/djangoprojects/djangoapp.
I also added the line WSGIScriptAlias /djangoapp /home/brian/djangoprojects/djangoapp/djangoapp/wsgi.py to the default Apache Virtual Host file and it works really nice.
However, in my application I'm using the auth module to register and login users, and have some problems with it. Sometimes I got redirected to the main page, http://example.com/, sometimes to http://example.com/register instead of http://example.com/djangoapp/register.
Changes I made in my project:
Edited settings.py and added:
LOGIN_URL = '/djangoapp/accounts/login/'
USE_X_FORWARDED_HOST = True
FORCE_SCRIPT_NAME = '/djangoapp'
SUB_SITE = "/djangoapp"
My urls.py file looks like this:
from django.conf.urls import include, url
from django.contrib import admin
from djangoapp import views
urlpatterns = [
url(r'^admin/', include(admin.site.urls)),
url(r'^$', 'django.contrib.auth.views.login'),
url(r'^logout/$', views.logout_page),
url(r'^accounts/login/$', 'django.contrib.auth.views.login'), # If user is not login it will redirect to login page
url(r'^register/$', views.register),
url(r'^register/success/$', views.register_success),
url(r'^home/$', views.home),
]
And here's my views.py file:
from django.contrib.auth.decorators import login_required
from django.contrib.auth import logout
from django.contrib.auth.models import User
from django.views.decorators.csrf import csrf_protect
from django.shortcuts import render_to_response
from django.http import HttpResponseRedirect
from django.template import RequestContext
from djangoapp.forms import RegistrationForm
#csrf_protect
def register(request):
if request.method == 'POST':
form = RegistrationForm(request.POST)
if form.is_valid():
user = User.objects.create_user(
username=form.cleaned_data['username'],
password=form.cleaned_data['password1'],
email=form.cleaned_data['email']
)
return HttpResponseRedirect('register/success/')
else:
form = RegistrationForm()
variables = RequestContext(request, {
'form': form
})
return render_to_response(
'registration/register.html',
variables,
)
def register_success(request):
return render_to_response(
'registration/success.html',
)
def logout_page(request):
logout(request)
return HttpResponseRedirect('/')
#login_required
def home(request):
return render_to_response(
'home.html',
{'user': request.user}
)
This is the production server and it's available online. I tried to use a work-around, but with no effect. I simply changed links on page and added djangoapp at the beginning, for instance:
{% extends "base.html" %}
{% block title %}Login{% endblock %}
{% block head %}Login{% endblock %}
{% block content %}
{% if form.errors %}
<p>Your username and password didn't match. Please try again.</p>
{% endif %}
<form method="post" action=".">{% csrf_token %}
<table border="0">
<tr><th><label for="id_username">Username:</label></th><td>{{ form.username }}</td></tr>
<tr><th><label for="id_password">Password:</label></th><td>{{ form.password }}</td></tr>
</table>
<input type="submit" value="Login" />
<input type="hidden" name="next" value="/home" />
</form>
Register
{% endblock %}
And I tried to change Register to Register but I'm sure there's got to be a smarter solution. Any advice?
You need to use the {% url %} tag and the reverse function consistently. So:
Register
and
return HttpResponseRedirect(reverse('register_success'))
For this to work you also need to give your URL patterns names:
url(r'^register/$', views.register, name="register"),
url(r'^register/success/$', views.register_success, name="register_success"),
Aso, as I said in the comment, you do not need to set FORCE_SCRIPT_NAME yourself.