Django] My registration form doesn't work - python

I'm coming to you because I have a problem with my form. Let me explain, when I enter the information in the inputs and I click on the button, it does absolutely nothing, without any error message.
This is views.py:
from django.shortcuts import render, redirect
from django.http import HttpResponseRedirect
from .models import Movies
from .forms import CreateUserForm
from django.contrib import messages
from django.contrib.auth.models import User
from django.contrib.auth import authenticate, login, logout
from django.conf import settings
from django.contrib.auth.decorators import login_required
# Create your views here.
def home(request):
context = {
'movies': Movies.objects.all()
}
return render(request, 'list/home.html', context)
#login_required(login_url='login-page')
def add(request):
return render(request, 'list/add.html', {'title': 'Add Movies'})
def signup(request):
if request.method == 'POST':
form = CreateUserForm(request.POST)
if form.is_valid():
form.save(commit=True)
return redirect('list-home')
else:
form = CreateUserForm()
return render(request, 'list/sign.html', {'form': form})
This is forms.py:
from django import forms
from django.contrib.auth.forms import UserCreationForm
from django.contrib.auth.models import User
class CreateUserForm(UserCreationForm):
username = forms.CharField(max_length=50, required=True, widget=forms.TextInput(attrs={"placeholder": "Your pseudo:"}))
first_name = forms.CharField(max_length=50, required=True, widget=forms.TextInput(attrs={"placeholder": ">Your first name:"}))
last_name = forms.CharField(max_length=50, required=True, widget=forms.TextInput(attrs={"placeholder": "Your last name:"}))
email = forms.EmailField( max_length=50, required=True, widget=forms.TextInput(attrs={"placeholder": "Your email:"}))
password = forms.CharField(max_length=50, required=True, widget=forms.PasswordInput(attrs={"placeholder": "Your password:"}))
password2 = forms.CharField(max_length=50, required=True, widget=forms.PasswordInput(attrs={"placeholder": "Confirm your password:"}))
class Meta:
model = User
fields = ('username', 'first_name', 'last_name', 'email', 'password', 'password2')
And my sign.html:
{% extends "list/base.html" %}
{% block content %}
<main class="site-main" style="background-color: black; color: white;">
<div class="form-box2">
<h1 style="text-align: center; padding: 20px;">SIGN UP</h1>
<form method="POST" class="conta" style="text-align: center;">
{% csrf_token %}
{{form.username}}
{{form.first_name}}
{{form.last_name}}
{{form.email}}
{{form.password}}
{{form.password2}}
<button type="submit">Sign up</button>
</form>
{% if messages%}
{% for message in messages%}
<div class="alert alert-{{message.tags }}">{{ message }}</div>
{% endfor %}
{% endif %}
</div>
</main>
{% endblock content%}
So here it is, I probably forgot something but I can't find it, I hope you can help me. Thank you in advance for your help.

You're creating a new form if the form is invalid, so there won't be any errors in that new form.
def signup(request):
form = CreateUserForm() # Form for GET request
if request.method == 'POST':
form = CreateUserForm(request.POST) # add the data from POST to the form
if form.is_valid():
form.save(commit=True)
return redirect('list-home')
# An invalid form will end up here with the errors in it.
return render(request, 'list/sign.html', {'form': form})
Looking at your template, because you're just rendering each field you also won't see the errors attached to a field.
While you're getting this up & running, try to get Django to do the most work for you. There may also be other errors, so you should include those if present;
{% if form.non_field_errors %}
<ul>
{% for error in form.non_field_errors %}
<li>{{ error }}</li>
{% endfor %}
</ul>
{% endif %}
{# To really make sure you debug this #}
{{ form.errors }}
<form method="POST" class="conta" style="text-align: center;">
{% csrf_token %}
{{ form.as_p }}
<button type="submit">Sign up</button>
</form>

Related

Django,Profile matching query does not exist error at profile/1

Whenever I click on the profiles(links) on the profile_list page, I get the profile doesn't exist error
it always goes to profiles that do not longer exist in the database.
Models.py:
from django.db import models
from django.contrib.auth.models import User
from django.db.models.signals import post_save
from django.dispatch import receiver
# Create your models here.
class Profile(models.Model):
user=models.OneToOneField(User,on_delete=models.CASCADE)
follows=models.ManyToManyField(
"self",
related_name="followed_by",
symmetrical=False,
blank=True)
def __str__(self):
return self.user.username
#receiver(post_save,sender=User)
def create_profile(sender, instance, created, **kwargs):
if created:
user_profile=Profile(user=instance)
user_profile.save()
user_profile.follows.add(instance.profile)
user_profile.save()
admin.py:
from django.contrib import admin
from django.contrib.auth.models import Group,User
from .models import Profile
class ProfileInline(admin.StackedInline):
model=Profile
class UserAdmin(admin.ModelAdmin):
model=User
fields=["username"]
inlines=[ProfileInline]
# Register your models here.
admin.site.unregister(Group)
admin.site.unregister(User)
admin.site.register(User,UserAdmin)
views.py:
from django.urls import reverse
from django.shortcuts import render
from requests import request
from users.models import Profile
from django.http import HttpResponseRedirect
# Create your views here.
def dashboard(request):
return render(request,"inbox/layout.html")
def feed(request):
return render(request,"inbox/feed.html")
def outbox(request):
return render(request,"inbox/outbox.html")
def profile_list(request):
profiles=Profile.objects.exclude(user=request.user)
return render(request,"inbox/profile_list.html",{"profiles":profiles})
def profile(request, pk):
if not hasattr(request.user, 'profile'):
missing_profile = Profile(user=request.user)
missing_profile.save()
profile = Profile.objects.get(pk=pk)
if request.method == "POST":
current_user_profile = request.user.profile
data = request.POST
action = data.get("follow")
if action == "follow":
current_user_profile.follows.add(profile)
elif action == "unfollow":
current_user_profile.follows.remove(profile)
current_user_profile.save()
return render(request, "inbox/profile.html", {"profile": profile})
profile.html:
<!-- inbox/templates/inbox/profile_list.html -->
{% extends 'inbox/layout.html' %}
{% block content %}
<form method="post">
{% csrf_token %}
<div >
<p>#{{ profile.user.username|upper }}</p>
<div class="buttons has-addons">
{% if profile in user.profile.follows.all %}
<button class="button is-success is-static">Follow</button>
<button class="button is-danger" name="follow" value="unfollow">
Unfollow
</button>
{% else %}
<button class="button is-success" name="follow" value="follow">
Follow
</button>
<button class="button is-danger is-static">Unfollow</button>
{% endif %}
</div>
<p1>following:</p1>
<ul>
{% for following in profile.follows.all %}
<li>{{ following }}</li>
{% endfor %}
</ul>
<p2>followers:</p2>
<ul>
{% for follower in profile.followed_by.all %}
<li>{{ follower }}</li>
{% endfor %}
</ul>
</div>
</form>
{% endblock content %}
profile_list.html template:
<!-- inbox/templates/inbox/profile_list.html -->
{% extends 'inbox/layout.html' %}
{% block content %}
<form method="post">
{% csrf_token %}
{% for profile in profiles %}
<div class="column">
<p>{{ profile.user.username }}</p>
<p>#{{ profile.user.username|lower }}</p>
</div>
{% endfor %}
</form>
{% endblock content %}
You need to match Profile's pk with profile = Profile.objects.get(pk=pk), currently you mentioned the pk of User model, which matched the given queryset in profile view, so try sending pk of profile in profile_list.html template:
{% for profile in profiles %}
<div class="column">
<p>{{ profile.user.username }}</p>
<p>#{{ profile.user.username|lower }}</p>
</div>
{% endfor %}
Also, it is better to use get_object_or_404 instead of get, as it calls get() on a given model manager, but it raises Http404 instead of the model’s DoesNotExist exception.
So, views.py:
def profile(request, pk):
if not hasattr(request.user, 'profile'):
missing_profile = Profile(user=request.user)
missing_profile.save()
profile = get_object_or_404(Profile, pk=pk)
if request.method == "POST":
current_user_profile = request.user.profile
data = request.POST
action = data.get("follow")
if action == "follow":
current_user_profile.follows.add(profile)
elif action == "unfollow":
current_user_profile.follows.remove(profile)
current_user_profile.save()
return render(request, "home/profile.html", {"profile": profile})
Now, if the profile does not exist, it will show no Profile matches the given query.

not able to open registration form page

trying to create a registration form, and I am facing an issue. so, below are my python pages:
form.py
from .models import User
from django import forms
from django.forms import ModelForm
class SignUpForm(ModelForm):
class Meta:
model = User
fields = ('username','password','email')
models.py
from django.db import models
#from django.core.urlresolvers import reverse
from django.contrib.auth.models import User
class Registration(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
urls.py
urlpatterns = [
url(r'^register/$', views.SignUpFormView, name= 'register'),
]
test.html
{% extends 'user_info/base.html' %}
{% block body %}
{% block content %}
<form method="POST">
{% csrf_token %}
{{ form }}
username:<br>
<input type="text" name="username"><br>
password:<br>
<input type="text" name="password"><br>
email:<br>
<input type="text" name="email"><br>
<input type="submit" value="Submit" />
</form>
{% endblock %}
{% endblock %}
views.py
def SignUpFormView(request):
template_name = 'test.html'
try:
if request.method == 'POST':
form = SignUpForm(request.POST)
if form.is_valid():
form.save()
username = form.cleaned_data.get('username')
password = form.cleaned_data.get('password')
email = form.cleaned_data.get('email')
return render(request, template_name, {'form':form})
except ValueError:
print("Oops! That was not a valid entry, try again...")
else:
SignUpForm()
return render(request, 'user_info/about.html')
The issue is, my "SignUpFormView" function in views.py is not entering the "if" statement, its directly going to "else". I seem to be lost here.
I have 'about.html'. I do not see any error as well. Which I find very weird. Please help.
Note: I am using Django's default in-built "User" model, and I do not wish to create any custom model.
Modified views.py
def SignUpFormView(request):
user_form = 'SignUpForm'
template_name = 'test.html'
if request.method == 'POST':
form = user_form(request.POST)
if form.is_valid():
form.save()
#username = form.cleaned_data.get('username')
#password = form.cleaned_data.get('password')
#email = form.cleaned_data.get('email')
#user.save()
return render(request, template_name, {'form':form})
else:
SignUpForm()
return render(request, 'user_info/about.html')
Modified forms.py
from .models import User
from django import forms
from django.forms import ModelForm
class SignUpForm(forms.ModelForm):
#password = forms.Charfield(widget=forms.PasswordInput)
class Meta:
model = User
fields = ('username','password','email')
modified test.html
{% extends 'user_info/base.html' %}
{% block body %}
{% block content %}
{% for error in form.errors %}
{{ form.errors | default_errors }}
{% endfor %}
<form method="post">
{% csrf_token %}
{{ form.as_p }}
{% for field in form %}
<p>
username:<br>
<input type="text" name="username"><br>
password:<br>
<input type="text" name="password"><br>
email:<br>
<input type="text" name="email"><br>
{% for error in field.errors %}
<p style="color: red">{{ error }}</p>
{% endfor %}
</p>
{% endfor %}
<button type="submit" value="Submit">sign up </button>
</form>
{% endblock %}
{% endblock %}

Django forms: Error message display all the time, not only after errors

I'm building my own site with Django's Framework.
I made a form for creating a new account. It works well but I have a problem with my errors messages.
All my errors are already display when I first arrive on the page. After submit, if a field is wrong, the page newly updated display only the wanted messages.
Here is a view of my page at my first arrival
So, my question is: How can I do for display the message only if a field is wrong ? I already succeed to personalize each messages.
I paste you my different django files:
views.py
#csrf_exempt
def create_new_user(request):
form = UserCreateForm(request.POST)
if request.method=="POST":
if form.is_valid():
user = form.save()
messages.info(request, "Merci pour votre enregistrement, vous etes maintenant connecte")
new_user = authenticate(username=form.cleaned_data['username'],
password=form.cleaned_data['password1']
)
login(request, new_user)
return HttpResponseRedirect('/')
return render_to_response('lejeudesbars/register.html', RequestContext(request, {'form': form}))
else:
return render(request, 'lejeudesbars/register.html', {'form': form})
forms.py
class UserCreateForm(UserCreationForm):
captcha = ReCaptchaField(error_messages={'required': 'Captcha: Validation obligatoire'})
email = forms.EmailField(required=True)
username = forms.CharField(error_messages={'required': 'Pseudo: Champ obligatoire'})
email = forms.EmailField(error_messages={'required': 'Email: Champ obligatoire'})
password1 = forms.CharField(widget=forms.PasswordInput(), error_messages={'required': 'Mot de passe: Champ obligatoire'})
password2 = forms.CharField(widget=forms.PasswordInput(), error_messages={'required': 'Mot de passe: Confirmation obligatoire'})
class Meta:
model = User
fields = ("username", "email", "password1", "password2")
def save(self, commit=True):
user = super(UserCreateForm, self).save(commit=False)
user.email = self.cleaned_data["email"]
if commit:
user.save()
return user`
index.html
<form method="post" action="/accounts/register/">
{% csrf_token %}
<h1>S'enregistrer</h1>
{{ form.username }}
{% if form.errors %}
<p class="error-msg-register">{{ form.username.errors }}</p>
{% endif %}
{{ form.email }}
{% if form.errors %}
<p class="error-msg-register">{{ form.email.errors }}</p>
{% endif %}
{{ form.password1 }}
{% if form.errors %}
<p class="error-msg-register">{{ form.password1.errors }}</p>
{% endif %}
{{ form.password2 }}
{% if form.errors %}
<p class="error-msg-register">{{ form.password2.errors }}</p>
{% endif %}
{{ form.captcha }}
{% if form.errors %}
<p class="error-msg-register">{{ form.captcha.errors }}</p>
{% endif %}
<input style="padding: 10px" type="submit" value="Créer mon compte" />
<input type="hidden" name="next" value="{{ next }}" />
</form>`
Thank you in advance for helping me !
(sorry for my bad english)
Thanks to Daniel Roseman, I've resolved my problem.
Here is my updated views.py:
views.py
#csrf_exempt
def create_new_user(request):
if request.method=="POST":
form = UserCreateForm(request.POST)
if form.is_valid():
user = form.save()
messages.info(request, "Merci pour votre enregistrement, vous etes maintenant connecte")
new_user = authenticate(username=form.cleaned_data['username'],
password=form.cleaned_data['password1']
)
login(request, new_user)
else:
form = UserCreateForm()
return render(request, 'lejeudesbars/register.html', {'form': form})
You should only pass request.POST into the field if it actually is a POST. So:
def create_new_user(request):
if request.method=="POST":
form = UserCreateForm(request.POST)
if form.is_valid():
...
else:
form = UserCreateForm()
return render(request, 'lejeudesbars/register.html', {'form': form})
You also don't need that intermediate return render_to_response(...).
In each field you have {% if form.errors %} - so when there is at least one error, you are going to display it everywhere.
change it to {% if form.field_name.errors %} and then html should render only the errors associated with that specific field

Comments not showing in post_detail view

I am doing a project in django 1.9.9/python 3.5, for exercise reasons I have a blog app, an articles app and a comments app. Comments app has to be genericly related to blog and articles. My problem is that the templates are not showing my comments. Comments are being created and related to their post/article because I can see it in admin, so it is not a comment creation problem. They are simply not showing in my template.
My comments/models.py:
from django.db import models
class Comment(models.Model):
post = models.ForeignKey('blog.Entry',related_name='post_comments', blank=True, null=True)
article = models.ForeignKey('articles.Article', related_name='article_comments', blank=True, null=True)
body = models.TextField()
created_date = models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.body
My commments/views.py:
from django.utils import timezone
from django.shortcuts import render, get_object_or_404
from django.shortcuts import redirect
from .forms import CommentForm
from .models import Comment
from blog.models import Entry
from articles.models import Article
from blog.views import post_detail
from articles.views import article_detail
def article_new_comment(request, pk):
article = get_object_or_404(Article, pk=pk)
if request.method == "POST":
form = CommentForm(request.POST)
if form.is_valid():
comment = form.save(commit=False)
comment.article = article
comment.created_date=timezone.now()
comment.save()
return redirect(article_detail, pk=article.pk)
else:
form=CommentForm()
return render(request, 'comments/add_new_comment.html', {'form': form})
def blog_new_comment(request, pk):
post = get_object_or_404(Entry, pk=pk)
if request.method == "POST":
form = CommentForm(request.POST)
if form.is_valid():
comment = form.save(commit=False)
comment.post = post
comment.created_date = timezone.now()
comment.save()
return redirect(post_detail, pk=post.pk)
else:
form=CommentForm()
return render(request, 'comments/add_new_comment.html', {'form': form})
And here is my post_detail.html, where comments should be. I will not post article_detail.html because they are exactly the same:
{% extends 'blog/base.html' %}
{% block content %}
<div class="post">
{% if post.modified_date %}
<div class="date">
{{ post.modified_date }}
</div>
{% else %}
<div class="date">
{{ post.published_date }}
</div>
{% endif %}
<a class="btn btn-default" href="{% url 'post_edit' pk=post.pk %}"><span class="glyphicon glyphicon-pencil"> Edit Post </span></a>
<h1>{{ post.title }}</h1>
<p>{{ post.text|linebreaksbr }}</p>
<hr>
<a class="btn btn-default" href="{% url 'new_blog_comment' pk=post.pk %}"><span class="glyphicon glyphicon-pencil"> Add Comment </span></a>
{% for comment in post.comments.all %}
<div class="comment">
<div class="date">{{ comment.created_date }}</div>
<p>{{ comment.body|linebreaksbr }}</p>
</div>
{% empty %}
<p>No comments here yet</p>
{% endfor %}
</div>
{% endblock %}
Let me know if any other file would help you to help me, like blog/models, views, although I don't think the problem is there.
You've explicitly set the related name of comments on your post to post_comments. So you would have to access them like:
{% for comment in post.post_comments.all %}
This is assuming post in your template refers to an instance of the Entry model.

{{ user.get_profile.foo }} not working in Django

I am trying to display user profile information in the users profile (original, I know,) but I can't get it to work unless it's the form view of the profile. I call user and foo in my user profile edit form with {{form.instance.user}} and it works fine.
I've implemented {{ user.get_profile.foo }} in my static user profile template (loggedin.html) but nothing happens.
My static user profile (loggedin.html) template looks like this:
{% extends "base.html" %}
{% block content %}
<title>{% block title %} | {{ username }}{% endblock %}</title>
<h2>Hi, {{ username }}!</h2>
<h3>{{ user.get_profile.foo }}</h3>
Edit Profile
{% endblock content %}
The view for loggedin.html:
def loggedin(request):
return render_to_response('loggedin.html', {'username':request.user.username, 'user':request.user})
My user profile edit form(profile.html) template:
{% extends "base.html" %}
{% block content %}
<title>{% block title %} | Edit Profile{% endblock %}</title>
<h2>Edit {{ username }}</h2>
{% for field in form %}
{{ field.error }}
{% endfor %}
<form action="/accounts/profile/" method="post">{% csrf_token %}
<label for="id_user">Username:</label>
<br>
<input id="id_user" name="user" type="text" value="{{form.instance.user}}">
<br><br>
<label for="id_foo">Foo:</label>
<br>
<input id="id_foo" name="foo" type="text" value="{{form.instance.foo}}">
<br><br>
<input type="submit" value="Update">
</form>
{% endblock content %}
My user profile (form) model:
from django.db import models
from django.contrib.auth.models import User
class UserProfile(models.Model):
user = models.OneToOneField(User)
foo = models.CharField(max_length=30)
User.profile = property(lambda u: UserProfile.objects.get_or_create(user=u)[0])
My user profile (form) view:
from django.shortcuts import render_to_response
from django.http import HttpResponseRedirect
from django.core.context_processors import csrf
from forms import UserProfileForm
from django.contrib.auth.decorators import login_required
from userprofile.models import UserProfile
#login_required
def user_profile(request):
user = request.user
username = request.user.username
if request.method == 'POST':
form = UserProfileForm(request.POST, instance=request.user.profile)
if form.is_valid():
form.save()
return HttpResponseRedirect('/accounts/loggedin')
else:
profile = user.profile
form = UserProfileForm(instance=profile)
args = {}
args.update(csrf(request))
args['form'] = form
args['user'] = user
args['username'] = username
return render_to_response('profile.html', args)
I can get the username and foo value to display fine in the user profile form, but when I try to get the same information to display in the static profile, it doesn't work.
Full disclosure: my static profile is in an app called polls which is different than the userprofile app where my edit form model and template are located, but I'm not sure if that has anything to do with this issue.
If you need to see my urls, settings, or admin code, let me know; I figured it wasn't relevant, and would just add clutter, but I'm happy to add it if needed.
Your property is User.profile. Therefore you should try
{{ user.profile.foo }}
in your template, instead of {{ user.get_profile.foo }}.

Categories

Resources