How to add permissions to users during registration in Django? - django

I have a registration method in views.py
def register_page(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'])
if request.POST.get("admin", ""):
content_type = ContentType.objects.get_for_model(User)
permission = Permission.objects.get(codename='admin_can_manage_users')
user.user_permissions.add(permission)
new_user = authenticate(username=form.cleaned_data['username'], password=form.cleaned_data['password1'])
login(request, new_user)
return redirect('payment_list')
form = RegistrationForm()
variables = RequestContext(request, {'form': form})
return render_to_response('registration/register.html',variables)
I also have a register form with standart fields and additional manually-added checkboxes. I want to check if one checkbox is checked and if so add permissions to users.
<form method="post" action=".">
{{ form.as_p }}
<input type="radio" class='radio-button' name="regular" id="regular"/><label for="regular">User</label>
<input type="radio" class='radio-button' name="manager" id="manager"/><label for="manager">Manager</label>
<input type="radio" class='radio-button' name="admin" id="admin"/><label for="admin">admin</label>
<input type="submit" value="register" />
</form>
Now permissions aren't assigned automatically. Previously I assigned this permission to first user and it worked but when I tried to assign it to another user got nothing.

Did you save the user?
user.user_permissions.add(permission)
user.save()
You can also turn the logs on and see what queries django does to database like this

The error was because of the namespace: my permission was in auth namespace. Just changed to another (another model) and it works perfectly.

Related

tags will not store in database in django

Tags will not store in database in Django
def addque(request):
if request.method == "POST":
user = request.user
if user.is_anonymous:
return redirect('addquery')
if user.is_active:
question = request.POST['question']
body = request.POST['body']
tags = request.POST['tags']
aquuid = request.user.aquuid
addquery = Question(question=question, user_id=aquuid, que_body=body, tags=tags)
addquery.save()
return redirect('addquery')
else:
return render(request, 'question/ask.html')
After giving the input the data is stored in the tags field but, not saving in the database. I can manually insert data through the admin panel successfully but not as a non-staff user. I have installed taggit and placed it in the installed_apps in settings.py. What is the issue with the code?
Tags are Many-to-Many objects and you can't add those to an object until the object has been saved. The documentation shows that you need to use .add() to add tags to a model instance. Your code should be:
addquery = Question(question=question, user_id=aquuid, que_body=body)
addquery.save()
addquery.tags.add(tags)
As an aside, you might be better served by a ModelForm which can handle the tags and all of this stuff that you're doing:
question = request.POST['question']
body = request.POST['body']
tags = request.POST['tags']
https://django-taggit.readthedocs.io/en/latest/forms.html
Use model form
In html use id of forms like this
HTML
<form action="{% url 'addquery' %}" method="post">
{% csrf_token %}
<div class="psrelative">
<input id="id_question" name="question" type="text" maxlength="300" tabindex="100" placeholder="e.g. Is there an R function for finding the index of an element in a vector?" class="s-input js-post-title-field" value="" data-min-length="15" data-max-length="150" autocomplete="off" required>
</div>
<textarea name="que_body" id="id_que_body" class="textarea-body"></textarea required>
<div class="psrelative">
<input id="id_tags" name="tags" type="text" maxlength="300" tabindex="100"
placeholder="e.g. (ruby-on-rails vba spring)" class="s-input js-post-title-field" value="" data-min-length="15" data-max-length="150" autocomplete="off" required>
</div>
<button class="review-question-btn" type="submit" tabindex="120"> Submit your question
</button>
</form>
Forms.py
from django import forms
from .models import Question
class Addqueform(forms.ModelForm):
class Meta:
model = Question
fields = ['question','que_body','tags']
Views.py
from .forms import Addqueform
def addque(request):
queform = Addqueform(request.POST)
if request.method == "POST":
user = request.user
if user.is_anonymous:
return redirect('addquery')
if user.is_active:
if queform.is_valid():
aquuid = request.user.aquuid
question = queform.cleaned_data['question']
body = queform.cleaned_data['que_body']
tags = queform.cleaned_data['tags']
addquery = Question(question=question, user_id=aquuid, que_body=body)
for tag in tags:
addquery.tags.add(tag)
addquery.save()
return redirect('addquery')
else:
queform = Addqueform()
return render(request, 'question/ask.html', {'form': queform})
else:
return render(request, 'question/ask.html', {'form': queform})
I think It will Work

Django #login_required causing issue when submitting forms

I am passing a some information to view function by submitting a form and view requires has #login_required decorator. Here is the template where i'm passing email ID using a from
<form action="{% url 'become_booster' %}" method="post">
{% csrf_token %}
<input type="hidden" name="email" value="{{ profile_user.email }}" />
<div class="form-group">
<div class="col-md-12 col-sm-12">
<input type="submit" class="btn btn-success btn-sm" value="Become a Booster">
</div>
</div>
</form>
Here is the view function
#login_required
def become_booster(request):
if request.method == "POST":
email = request.POST.get('email')
user = CustomUser.objects.filter(email= email)[0]
tiers = Tiers.objects.filter(user=user)
form = SubscriptionForm
return render(request,'select_tier.html',{'tiers':tiers,'form':form})
This is working fine when the user logedin already. When user didn't login, #login_required sends them to login and when it comes back request.method is no longer POST. It no longer has that email info. Can someone help me with this. Thanks!
#login_required decorator is used to available that function to registered user who are actually logged in or send to login page or registration page. if you remove #login_required from your view function it will be available for unregistered and all type of users.
Try this,
from django.shortcuts import *
#login_required(login_url='become_booster')
def become_booster(request):
if request.method == "POST":
email = request.POST.get('email')
user = get_object_or_404(CustomUser, email=email)
tiers = get_list_or_404(Tiers, user=user)
form = SubscriptionForm
return render(request,'select_tier.html',{'tiers':tiers,'form':form})
elif request.method == 'GET':
# Something like this
# return render(request, 'your_template.html', {'profile_user': user_object_which_contains_email})

How can I store form input in a session in Django?

Who can help me with the following challenge?
I have a registration template where users can sign up. They are then redirected to an url with a payment button and activated when a successful payment is made. In the HTML template I store the username in a custom field within the payment button which is used to later activate the account. Now since the user is not activated/logged in yet, I can't call the user object yet like {{user.username}}. So I want to try sessions to solve this and capture the username during registration to retrieve this session variable and put it in my custom field on a different page. But how? I tried using request.session but I’m not sure where to fit this the files below and then how to call this variable in the html template.
Any advise or help is greatly appreciated!
Here is my regbackend.py
class MyRegistrationView(RegistrationView):
form_class = UserProfileRegistrationForm
def register(self, form_class):
user_package.username = form_class.cleaned_data['username']
And here my forms.py
class SignUpForm(forms.ModelForm):
class Meta:
model = SignUp
fields = ['username', 'email']
Here my registration.html
<form method="post" action=".">
{% csrf_token %}
{{ form.username|as_crispy_field }}
<input class="btn btn-success" type="submit" value="{% trans 'Submit' %}" /></form>
And finally my HTML Template for after registration with the payment button and custom field.
<form action="some-url" method="post" target="_top">
<input type="hidden" name="custom" value="{{ session.username? }}">
</form>
Im using Django 1.9x and Django-registration-redux
This is how I keep the session to use it on another view.
On your registration form :
def registration(request):
initial={'username': request.session.get('username', None)}
form = RegistrationForm(request.POST or None, initial=initial)
if request.method == 'POST':
if form.is_valid():
request.session['username'] = form.cleaned_data['username']
return HttpResponseRedirect(reverse('your_checkout_view'))
return render(request, 'registration.html', {'form': form})
Once the username field is completed and the form submited it goes to the second view in which you can take the username that is stored in your session.
Just like this :
def your_checkout_view(request):
username = request.session['username']
...
From there you can take the stored username and do what you have to do.

Signup then login a user with Django

I have a simple signup form (in signup.html)
<form action="adduser" method="post">
{% csrf_token %}
Email Address: <input type="email" name="email" required autocomplete="on" placeholder="fr#star.com"/><br/>
Username: <input type="text" name="username" maxlength=25 required placeholder="JoyfulSophia"/><br/>
Password: <input type="password" name="password" maxlength=30 required placeholder="**********" /><br/>
<br/>
<input type="submit" value="Send" /> <input type="reset">
</form>
This redirects to the addUser view:
def adduser(request):
u = User.objects.create_user(request.POST['username'], request.POST['email'], password=request.POST['password'])
u.save()
a = Accounts(user=u)
p = Passwords(user=u)
a.save()
p.save()
return HttpResponseRedirect(reverse('OmniCloud_App.views.profile', args=(u.id,)))
Here is the profile:
#login_required
def profile(request, User_id):
u = get_object_or_404(User, pk=User_id)
a = get_object_or_404(Accounts, pk=User_id)
return render_to_response('profile.html', context_instance=RequestContext(request))
So they wouldn't be signed in, but that's okay because we can send you over to /accounts/login?next=/7/ since they are user 7 (Problems Ahead!)
def login(request):
username = request.POST['username']
password = request.POST['password']
user = auth.authenticate(username=username, password=password)
if user is not None and user.is_active:
auth.login(request, user)
return HttpResponseRedirect("/account/profile/")
else:
return HttpResponseRedirect("/account/invalid/")
The request doesn't contain anything called username, but the one which was submitted to the addUser form does, so how can I shoot that bro over to login? I could have it parse the url (which contains the next=USER_ID) but that wouldn't work for someone that just types in base_url/login, and the user_id won't be part of the url forever. So what's a brother to do?
Post data exists only for one request. If you want to use it later you should save it somewhere else.
You could login the user right after registration, in adduser view, he just entered his username and password, he doesn't have to do it again.
And login view is a little off. This is just a "POST" part of the view. You need to check and see if it's GET request and if it is return template with form containing username and password fields and with target url that points to the same view. Something like this:
def login(request):
if request.method == 'GET':
return render_to_response('login.html',
{ 'form': LoginForm() },
context_instance=RequestContext(request))
elif request.method == 'POST':
form = LoginForm(request.POST)
if form.is_valid():
username = form.cleaned_data['username']
password = form.cleaned_data['password']
user = auth.authenticate(username=username, password=password)
if user is not None and user.is_active:
auth.login(request, user)
return HttpResponseRedirect("/account/profile")
else:
return HttpResponseRedirect("/account/invalid/")
Where login.html is something like this:
{% extends "base_site.html" %}
{% block content %}
<form method="post" target="{% url login_view %}">
{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="Login" />
</form>
{% endblock content %}
Also, you could return user to the same login form if username and password didn't match and add some message!
This is just from the top of my head, didn't try it, but it should work!
There is an extensible user-registration application for Django called django-registration that offers you a lot of functionality for creating and registering users. Setting it up is very simple, you can find a very good doc here

Django Redirect to current page

I am having troubles with the redirect to the same page user was on after logging in, no matter how hard I tried and read all the questions here. I think it is high time I showed folks out here my code so if you can point out mistake(s). Thanks.
My login url (in base.html template):
This is present on every page. Changes to logout once the user is logged in. I read that I have to pass a param for example 'next' like this:
Login
but,
*The {{request.path}} is always empty. *
login view:
def mylogin(request):
"""login view"""
try:
redirect_to = request.GET.get('next', '/')
except ValueError:
redirect_to = "/"
errors = ''
t = loader.get_template('login.html')
# check for POST data
if request.method == 'POST':
username = request.POST['username']
password = request.POST['password']
user = authenticate(username=username, password=password)
if user is not None:
if user.is_active:
login(request, user)
# Redirect to a success page.
return HttpResponseRedirect(redirect_to)
else:
c = Context({
'errors':'disabled',
})
return HttpResponse("disabled")
else:
c = Context({
'errors':'incorrect',
})
return HttpResponse(t.render(c))
else:
c = Context({
'errors':None,
})
return HttpResponse(t.render(c))
The login form, in login.html template
<form method="post" action="?next={{ redirect_to }}" >
<p><label for="username">Username</p>
<p></label><input type="text" name="username" value="" id="username" /></p>
<p><label for="password">Password</label></p>
<p><input type="password" name="password" value="" id="password" /></p>
<p><input type="submit" value="Login"></p>
</form>
You're not passing request to the template context, so naturally it's empty. The easiest way to get it in there is to use a RequestContext, which uses the built-in context processors to add variables to the context.
The usual way to do this is to use render_to_response with the extra parameter context_instance=RequestContext(request). For some reason, you're rendering all your templates the long way, so you'll need to create that requestcontext yourself.
You'll also need to add django.core.context_processors.request to the CONTEXT_PROCESSORS tuple ins settings.py.