Trying to create a simple user registration form in django. Here is my views.py-
def registerPage(request):
form=UserCreationForm()
if request.method == 'POST':
form=UserCreationForm(request.POST)
if form.is_valid():
form.save()
context = {'form':form}
return render(request, 'newapp/register.html', context)
And my html template-
<h3>Register</h3>
<form method="POST" action="">
{% csrf_token %}
{{form.as_p}}
<input type="submit" name="Create User">
</form>
In the views I imported UserCreationForm like this and following is the url which is working fine-
from django.contrib.auth.forms import UserCreationForm
url-
path('register/', views.registerPage, name="register"),
When I try to create a user the form seems to work fine but the user is never created in the admin. It doesn't show up.I refreshed the page and all. There is no error. I created a user from the admin panel just to make sure and it works.
Earlier same form was giving me a CSRF token failure. Rebooting the computer that error went away. Now no error, but also no user.
Curious with no error in sight, when can be reason for this to happen?
Here is how the CMD looks like after few attempts of user creation, see if that gives you any clue-
Never mind guys. i just had to import the User model to forms.py and create a form of my own and it did the trick.
Thank you all.
Related
What is the Django way of creating a User?
I am not talking about the super user, just a simple form for users and creating an account
The Django docs cover the topic of authentication quite well, and Django itself ships with views for login, logout, password change, and reset. For registration, you'll have to create your own view, something like this:
from django.contrib.auth.forms import UserCreationForm
from django.contrib.auth.models import User
from django.http import HttpResponse
from django.shortcuts import render
def create_user(request):
if request.method == 'POST':
form = UserCreationForm(request.POST)
if form.is_valid():
form.save()
return HttpResponse("User created successfully!")
else:
form = UserCreationForm()
return render(request, 'auth/create_user.html', {'form': form})
This uses Django's built-in User creation form, which expects a username and two passwords, for verification. Your template would look something like this:
<form action='/create-user/' method='post'>
{% csrf_token %}
{{ form }}
<input type="submit" value="Submit" />
</form>
Registration is not a part of Django framework, AFAIK. I can recommend django-registration (https://django-registration.readthedocs.io) application. It does require some custom template, but can save a lot of trouble with writing your own sign up views.
I have a project with a Post model, that is basic posts. I want to create a link on each post page to be able to delete that post (with appropriate security).
There are a few questions on this on stack overflow, but I can't seem to find a complete, workable answer (I am using Django 1.7) that doesn't throw up errors when I implement it.
I have been able to implement a delete function which works ok, but need to add a POST form with CSRF token for validation, and also check that the user deleting it is the one that created it. I can't seem figure out how to add these two in.
So far, in my views.py:
def delete(request, id):
post = Post.objects.filter(pk=id).delete()
return HttpResponseRedirect(reverse('posts.views.all_posts'))
In urls.py:
url(r'^delete/(?P<id>\d+)/$','posts.views.delete'),
In html:
Delete
This all works, but there is no security - so appreciate guidance on how to add a form and checking.
Also, I've seen an answer that uses DeleteView, but couldn't get that one to work either.
Indeed, using a GET method to delete your objects makes you vulnerable to CSRF attacks.
DeleteView only deletes on POST, and shows a confirmation page on GET.
Your code should look something like this in views.py:
from django.views.generic import DeleteView
class PostDelete(DeleteView):
model = Post
success_url = reverse_lazy('posts.views.all_posts')
In urls.py:
url(r'^delete/(?P<pk>\d+)/$', PostDelete.as_view(),
name='entry_delete'),
Your form (without using a confirmation template. There is an example of confirmation template in the docs):
<form action="{% url 'entry_delete' object.pk %}" method="post">
{% csrf_token %}
<input type="submit" value="Delete" />
</form>
If you are not using a confirmation template, make sure to point the form's action attribute to the DeleteView (this is why).
To ensure the user deleting the post is the user that owns it, I like to use mixins. Assuming your Post model has a created_by foreign key pointing to User, you could write a mixin like:
from django.core.exceptions import PermissionDenied
class PermissionMixin(object):
def get_object(self, *args, **kwargs):
obj = super(PermissionMixin, self).get_object(*args, **kwargs)
if not obj.created_by == self.request.user:
raise PermissionDenied()
else:
return obj
Finally, your DeleteView should inherit from this mixin:
class PostDelete(PermissionMixin, DeleteView):
model = Post
success_url = reverse_lazy('posts.views.all_posts')
I am facing a problem while building a Django web app. I want that if a user logs into his account, his session should be stored and when he agains visits the login page ,he should be redirected to his home page.
Here is my code.
Views.py
from django.http import HttpResponse
from django.shortcuts import render_to_response
from django.contrib.auth.decorators import login_required
from django.template import RequestContext
def index(request):
return HttpResponse("Index Page")
#login_required
def home(request):
ctx = {}
return render_to_response('auth/home.html',ctx, context_instance = RequestContext(request))
def login_page(request):
if request.user.is_authenticated():
return redirect('cc_home')
else:
return render_to_response(request,'auth/cc.html')
Urls.py
from django.conf.urls.defaults import *
from django.contrib.auth.views import login, logout
urlpatterns = patterns('',
url(r'cc/', 'apps.auth.views.login_page', name = 'cc_login'),
url(r'logout/', logout, name = 'cc_logout'),
url(r'home/','apps.auth.views.home', name = 'cc_home'),
)
And here is my template cc.html
<form action ="." method = POST>
{% csrf_token %}
{{ form.as_p }}
<input type = "submit" value = "login">
</form>
</body>
home.html
{{ user }} 's profile
Logout
When I browse to CC url it should first asks the user's credentials. After successful login, it should redirect to the user's home url, which is running fine. But, when the user again browse to CC url (), he should be redirected it to his home page.
While Debugging, I found that it is not able to render the form when the user is not authenticated. It does not shows the Django's inbuilt form provided in the CC.html, it just shows the Login button.
How do I render the form. Kindly suggest.
Thanks
But you haven't passed any form to the template to render! You need to instantiate the login form and pass it to the template context, otherwise {{ form }} doesn't refer to anything.
You should be able to use the default form if you replace;
url(r'cc/', 'apps.auth.views.login_page', name = 'cc_login'),
with;
url(r'cc/', login, {template_name: 'cc.html'}),
May be the error is in the login_page method. try to fix it like this
def login_page(request):
if request.user.is_authenticated():
return redirect('cc_home')
else:
return render_to_response('auth/cc.html',{} context_instance = RequestContext(request))
i believe that the request in your render_to_response cause the problem
I'm trying to make it so a user can upload an avatar to their UserProfile, but I keep getting the following error:
IntegrityError at /~csihar/userpic
null value in column "user_id" violates not-null constraint
DETAIL: Failing row contains (4, null, userpics/image.jpg).
...with the first value incrementing by 1 each time I try to upload. I've attempted to instantiate the form with the user's current profile before saving, as well as excluding irrelevant fields from the modelform, but it still isn't working and I'm not sure what I'm overlooking. However, the image does get saved to my MEDIA_ROOT before the error occurs.
models.py:
from django.contrib.auth.models import User
from django.forms import ModelForm
from django_resized import ResizedImageField
class UserProfile(models.Model):
user = models.OneToOneField(User)
userpic = ResizedImageField(max_width=100, max_height=100, upload_to='userpics/')
class UserpicUpload(ModelForm):
class Meta:
model = UserProfile
exclude = ('user','user_id')
views.py:
from django.shortcuts import render_to_response
from django.http import HttpResponseRedirect
from django.template import RequestContext
from items.models import User, UserProfile, UserpicUpload
from django.contrib.auth.decorators import login_required
#login_required
def userpic(request,list_owner):
current_user = User.objects.get(pk=request.user.id)
current_profile = current_user.get_profile()
if request.method == 'POST':
form = UserpicUpload(request.POST, request.FILES, instance=current_profile)
if form.is_valid():
newuserpic=UserProfile(userpic=request.FILES['userpic'])
newuserpic.save()
gohomeurl = "/~" + request.user.username
return HttpResponseRedirect(gohomeurl)
else:
form = UserpicUpload()
return render_to_response('userpic.html', {'listowner': list_owner, 'form':form}, RequestContext(request))
forms.py:
from django import forms
class UserpicUpload(forms.ModelForm):
userpic = forms.ImageField()
template (userpic.html):
{% extends 'base.html' %}
{% block body %}
<form action="" method="post" enctype="multipart/form-data">{% csrf_token %}
<p>{{ form.non_field_errors }}</p>
<p>{{ form.userpic.errors }}</p>
<p>{{ form.userpic }}</p>
<p><input name="submit" value="Upload" type="submit" />
</form>
{% endblock %}
Turns out I was going about it all wrong and was creating new profiles rather than adding to an existing one. The problem was fixed by replacing the following lines in views.py:
newuserpic=UserProfile(userpic=request.FILES['userpic'])
newuserpic.save()
...with this:
newuserpic=request.FILES['userpic']
current_profile.userpic=newuserpic
current_profile.save()
Now I'm having issues getting the pic to display properly on the user's home page, but that's a whole separate issue that probably has to do with my MEDIA_URL - at least the pic is getting saved properly now!
In your view.py you have the following code:
if form.is_valid():
newuserpic=UserProfile(userpic=request.FILES['userpic'])
newuserpic.save()
but you do not seem to associate the new profile with a user, I suspect this is why the error is raised. Something like
newuserpic.user = request.user
...might do the trick. I'm posting this answer just by reading your code, so please be gentle :)
EDIT: If you want to edit the existing profile of the current user instead of creating a new one you should do the following in your view:
if form.is_valid():
u_profile=request.user.get_profile()
u_profile.userpic = request.FILES['userpic']
u_profile.save()
We first access the user profile, then edit the userpic property and finally save it.
I'm having a problem with saving and updating a value to my database.
View:
def code_prof_edit(request, ampCode):
user_code = get_object_or_404(CodeUser, pk=ampCode)
if request.method =='POST':
form = CodeUserForm(request.POST, instance=user_code)
if form.is_valid():
form.save()
return HttpResponseRedirect('/codes/' + user_code.ampCode)
else:
form = CodeUserForm(instance=user_code)
return render_to_response('edit_code_user.html', {'user_code':user_code, 'form':form})
Relevant template form tag:
<form action="." method="POST"> {% csrf_token %}
{{form.as_p}}
<input type="submit" value="Save" />
</form>
Using the post method, the form correctly renders in the browser with all of the original values pre-populated, but if I change the values and click submit, none of the changes are made. Everything seems to work correctly in that the user is redirected to the correct page which means the save must have been called, but the info typed isn't being saved. Any and all help would be appreciated.
Edit entire view function:
from django.shortcuts import render_to_response, get_object_or_404
from django.http import *
from django.template import RequestContext
from codeuser.models import CodeUser
from codeuser.forms import CodeUserForm
import pdb
def code_prof_edit(request, ampCode):
user_code = get_object_or_404(CodeUser, pk=ampCode)
if request.method =='POST':
pdb.set_trace()
form = CodeUserForm(request.POST, instance=user_code)
if form.is_valid():
form.save()
return HttpResponseRedirect('/codes/' + user_code.ampCode)
else:
return render_to_response('home.html')
else:
form = CodeUserForm(instance=user_code)
return render_to_response('edit_code_user.html', {'user_code':user_code, 'form':form})
Edit: Figured it out. In the html form tag, the action attribute was incorrect. "." wasn't working, I needed "./edit" to get the correct result. Also, excluding that attribute all together worked perfectly too.