I am trying to allow users to deactivate their accounts on my django website. Here is what I have tried:
views.py
from django.contrib.auth.models import User
#login_required
def deactivate_user(request, username):
context = {}
try:
user = User.objects.get(username=username)
user.is_active = False
user.save()
context['msg'] = 'Profile successfully disabled.'
except User.DoesNotExist:
context['msg'] = 'User does not exist.'
except Exception as e:
context['msg'] = e.message
return render(request, 'index.html', context=context)
urls.py
path('deactivate-user/<slug:username>', deactivate_user, name='deactivate_user'),
base.html
<form action="{% url 'users:deactivate_user' slug=username.slug %}" method="post">
{% csrf_token %}
<button type="submit" class="active">Yes, Deactivate</button>
<button type="button" data-dismiss="modal">Cancel</button>
</form>
I am getting a NoReverseMatch error Reverse for 'deactivate_user' with keyword arguments '{'slug': ''}' not found. 1 pattern(s) tried: ['users/deactivate\\-user/(?P<username>[-a-zA-Z0-9_]+)$'] Have tried a few different parameters in the template but can't get anything to work.
You are saying
<form action="{% url 'users:deactivate_user' slug=username.slug %}" method="post">
slug isn't a keyword in your pattern, its a type, similar to <int:pk>, it should be username=username.slug
Related
I am a beginner with django.
I want to get a parameter that the user has to enter from a form. This parameter must be visible in the url except that the django server returns an error because the parameter is empty.
Here is what I did:
This is my template:
<form method="POST" action="{% url 'direct_aeg' id_aeg %}" enctype="multipart/form-data">
{% csrf_token %}
{{form}}
<div class="input-field button"><input type="submit" name="submit_btn" value="Recherche AEG"></div>
</form>
this is my forms.py:
from django import forms
class Form_direct_aeg(forms.Form):
id_aeg = forms.IntegerField(label="N° AEG",required=True)
this is my views.py
def direct_aeg(request,id_aeg):
# doing some_stuff
def show_aeg_tool(request):
if request.method == 'POST':
form = Form_direct_aeg(request.POST)
if form.is_valid():
id_aeg = form.cleaned_data['id_aeg']
url = str(id_aeg)
return redirect(url)
else:
form = Form_direct_aeg()
return render(request, 'home/select_suivi_aeg.html', context={
'form': form,
})
this is my urls.py
path('a/b/c/d/direct_aeg/<int:id_aeg>', aeg.direct_aeg, name='direct_aeg'),
as soon as I load the page I get the following error:
Reverse for 'direct_aeg' with arguments '('',)' not found. 1 pattern(s) tried: ['a/b/c/d/direct_aeg/(?P<id_aeg>[0-9]+)\\Z']
I have this error because the id_aeg parameter must be initialized. How to solve this problem?
I have a problem with update of my DetailView, so once i try to submit the updated values I am receiving an error NoReverseMatch at /task/164/. Could you please give me a hint what is wrong?
Thx!
urls:
path('excel_upload', ex_views.ExcelUploadView.as_view(), name='excel-upload'),
path('user_list', ex_views.UsersListView.as_view(), name = "user-list"),
path('excel_table', ex_views.ExcelTableView.as_view(), name = "excel-table"),
path("task/add", ex_views.TaskAddView.as_view(), name="task-add"),
path("task/<int:pk>/", ex_views.TaskDetailView.as_view(), name="task-detail"),
forms.py
class AddEditTaskForm(forms.ModelForm):
class Meta:
model = Task
exclude = ['created_by']
widgets = {
"due_date": forms.DateInput(attrs={'type':'date'}),
"completed_date": forms.DateInput(attrs={'type': 'date'}),
"name":forms.TextInput(),
"note": forms.Textarea(),
}
views.py
class TaskDetailView(DetailView):
model = Task
template_name = "hana/task_detail.html"
# Add POST method
def post(self, request, pk):
task = get_object_or_404(Task, pk=pk)
form = AddEditTaskForm(request.POST, instance=task)
if "add_edit_task" in request.POST:
if form.is_valid():
form.save()
messages.success(request, "The task has been edited.")
return redirect('excel-table')
return render(request, 'hana/task_detail.html', {'form': form})
error:
NoReverseMatch at /task/164/
Reverse for 'task-detail' with arguments '('',)' not found. 1 pattern(s) tried: ['task\/(?P[0-9]+)\/$']
Request Method: POST
Request URL: http://127.0.0.1:8000/task/164/
Django Version: 3.0.6
Exception Type: NoReverseMatch
Exception Value:
Reverse for 'task-detail' with arguments '('',)' not found. 1 pattern(s) tried: ['task\/(?P[0-9]+)\/$']
Exception Location: /home/lukasz/envtest2/lib/python3.6/site-packages/django/urls/resolvers.py in _reverse_with_prefix, line 677
template:
<form method="post" action="{% url 'task-detail' object.id %}" role="form" class="d-inline">
{% csrf_token %}
<div style="display:inline;">
<button class="btn btn-info btn-sm" type="submit" name="toggle_done">
{% if task.completed %} Mark Not Done {% else %} Mark Done {% endif %}
</button>
</div>
</form>
<a class="btn btn-danger btn-sm mt-1 mb-1" href={% url 'task-delete' object.id %}">Delete</a>
Your issue is caused by mixing class based and function based views. Your function based post view uses the same template as your class based TaskDetailView, but since it doesn't have the same "magic" inherited from DetailView, there is no object passed in the context dictionary (you only pass form).
The proper fix would be to stick to the same view architecture when possible, but a trivial fix would be:
return render(request, 'hana/task_detail.html', {'form': form, 'object': task})
I have an error stating Method not Allowed (POST). But I have a Post method in my view. That's the only method that I have on my view.
class AddOrRemoveFollower(LoginRequiredMixin, View):
def post(self, request, *args, **kwargs):
#import ipdb; ipdb.set_trace()
other_user = get_object_or_404(User, pk=kwargs['pk'] )
current_user = request.user
if current_user is other_user:
messages.success(request, 'You cannot follow yourself')
return redirect(reverse('myfriendship:friends'))
if current_user not in Follow.objects.followers(other_user):
Follow.objects.add_follower(request.user, other_user)
messages.success(request, 'You are now following a user')
return redirect(reverse('myfriendship:friends'))
else:
Follow.objects.remove_follower(request.user, other_user)
messages.success(request, 'You decided to unfollow this user')
return redirect(reverse('myfriendship:friends'))
urls.py
url(r'^AddOrRemoveFollower/(?P<pk>\d+)/$',
views.AddOrRemoveFollower.as_view(),
name='AddOrRemoveFollower'),
shell
WARNING:django.request:Method Not Allowed (POST): /myfriendship/AddOrRemoveFollower/1/
WARNING:django.server:"POST /myfriendship/AddOrRemoveFollower/1/ HTTP/1.1" 405 0
html
<form class="right" method="POST" action="{% url 'myfriendship:AddOrRemoveFollower' user.id %}">
{% csrf_token %}
<input type="hidden" name="course_id" value="{{user.id}}">
<input class="btn btn-primary btn-sm red darken-2" type="submit" value="{% can_follow user request.user %}">
</form>
You try to post to the detail, POST method in class base view allowed only without pk. Try PUT or PATCH.
I am using a custom user model for my Django project and I can log in via /admin/ perfectly fine. But when I go to /accounts/login and try to log in, it just bounces me back to the login page without logging in. I am using django-registration-redux with the simple backend.
Via logging I discovered that the error happens in this method in django.contrib.auth.__init__.py:
def get_user(request):
"""
Returns the user model instance associated with the given request session.
If no user is retrieved an instance of `AnonymousUser` is returned.
"""
from .models import AnonymousUser
user = None
try:
#
# EXCEPTION THROWN ON BELOW LINE
#
user_id = _get_user_session_key(request)
backend_path = request.session[BACKEND_SESSION_KEY]
except KeyError:
pass
else:
if backend_path in settings.AUTHENTICATION_BACKENDS:
backend = load_backend(backend_path)
user = backend.get_user(user_id)
# Verify the session
if hasattr(user, 'get_session_auth_hash'):
session_hash = request.session.get(HASH_SESSION_KEY)
session_hash_verified = session_hash and constant_time_compare(
session_hash,
user.get_session_auth_hash()
)
if not session_hash_verified:
request.session.flush()
user = None
return user or AnonymousUser()
Any ideas? /accounts/register/ performs as expected, although I have overridden RegistrationView. Perhaps I have to do the same thing for logging in?
Login.html
{% extends "base.html" %}
{% load staticfiles %}
{% block body_block %}
<link href="{% static 'css/signin.css' %}" rel="stylesheet">
<div class="container">
<div class="jumbotron">
<h1 class="display-3" align="center">Login</h1>
</div>
<form method="post" action=".">
{% csrf_token %}
<h2 class="form-signin-heading">Please sign in</h2>
<label for="inputEmail" class="sr-only">Username</label>
<input type="text" name="email" id="id+username" class="form-control" placeholder="Username" required autofocus>
<label for="inputPassword" class="sr-only">Password</label>
<input type="password" name="password" id="id_password" class="form-control" placeholder="Password" required>
<button class="btn btn-lg btn-primary btn-block" type="submit" value="Submit">Login</button>
</form>
Not a member?
Register
</div>
<p>
</p>
{% endblock %}
Urls.py
class MyRegistrationView(RegistrationView):
success_url = '/'
form_class = UserProfileRegistrationForm
def get(self, request, *args, **kwargs):
form = self.form_class(initial=self.initial)
return render(request, self.template_name, {'form': form})
def register(self, form):
logging.debug("THIS IS MY REGISTER")
new_user = form.save(commit=False)
new_user.set_password(form.cleaned_data['password1'])
new_user.save()
login(self.request, new_user)
logging.debug("Logged in")
signals.user_registered.send(sender=self.__class__,
user=new_user,
request=self.request)
logging.debug("After signals")
return new_user
urlpatterns = [
url(r'^', include('base.urls')),
url(r'^admin/', admin.site.urls),
url(r'^accounts/register/$', MyRegistrationView.as_view(), name="registration_register"),
url(r'^accounts/password/change/$', MyRegistrationView.as_view(), name="auth_password_change"),
url(r'^accounts/password/change/done/$', MyRegistrationView.as_view(), name="auth_password_changed"),
url(r'^accounts/', include('registration.backends.simple.urls')),
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
EDIT:
I have a temporary fix of throwing a view into login in urls.py. Something tells me this is extremely dirty but it seems to work... for now. I'm open to better alternatives.
url(r'^accounts/login/$', my_view, name="login"),
def my_view(request):
if request.POST:
username = request.POST['email']
password = request.POST['password']
user = authenticate(username=username, password=password)
if user is not None:
login(request, user)
return render(request, 'index.html', {})
# Redirect to a success page.
else:
# Return an 'invalid login' error message.
pass
else:
return render(request, 'registration/login.html', {})
Try using {{ form }} in your login template, instead of rendering the fields manually. This can show whether the problem is in your template or elsewhere.
In this case, I think that the form fields should be username and password, not email and password as you have.
<input type="text" name="username" id="id_username" class="form-control" placeholder="Username" required autofocus>
<input type="password" name="password" id="id_password" class="form-control" placeholder="Password" required>
I want to redirect a homepage after login in, but the request.user is always anonymous.Where the errors hide?
the code:
urls.py
urlpatterns = patterns('',
url(r'^login/$', login_view),
url(r'^main/$', main_view,name='main'),
)
i have a login form named forms.py
class LoginForm(forms.Form):
username = forms.CharField(required=True,
label='',
max_length=12,
error_messages={'required':'username'},
widget=forms.TextInput(
attrs={'placeholder':'username',
'class':'form-control'}))
password = forms.CharField(required=True,
label='',
max_length=12,
min_length=6,
error_messages={'required':'password'},
widget=forms.PasswordInput(
attrs={'placeholder':'password',
'class':'form-control'}))
def clean(self):
if not self.is_valid():
raise forms.ValidationError('username and password are required')
else:
cleaned_data = super().clean()
the view file:
def login_view(request):
if request.method == 'GET':
form = LoginForm(auto_id=False)
return render_to_response('game/login.html',
RequestContext(request, {'form': form,}))
else:
form = LoginForm(request.POST)
if form.is_valid():
username = request.POST.get('username', '')
password = request.POST.get('password', '')
user = auth.authenticate(username=username,
password=password)
if user is not None and user.is_active:
auth.login(request, user)
return render_to_response('game/main.html',
context_instance=RequestContext(request))
else:
return render_to_response('game/login.html',
RequestContext(request,
{'form': form,'password_is_wrong':True}))
else:
return render_to_response('weapon/login.html',
RequestContext(request, {'form': form,}))
#login_required(login_url='/game/login/')
def main_view(request):
user = request.user
return render_to_response('weapon/main.html',
{'user':user},
context_instance=RequestContext(request))
login.html include:
<form class="form-signin" role="form" action="{% url 'game:main' %}" method="post">
{% csrf_token %}
<h2 class="form-signin-heading">Login in</h2>
{{ form.as_p }}
<label class="checkbox">
<input type="checkbox" value="remember-me"> remember me
</label>
<button class="btn btn-lg btn-primary btn-block" type="submit">Login</button>
</form>
main.html include:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
{% if user.is_authenticated %}
{{ user.username }} Successful
{% else %}
failed
{% endif %}
</body>
</html>
Any suggestions would be much appreciated.
After login you are redirecting the user to game/main.html whereas in my opinion you should redirect user to main_view instead.
The code block in views.py should be:-
EDITED:
if user is not None and user.is_active:
auth.login(request, user)
return HttpResponseRedirect('/game/main')
The form in your login template is pointing to the main view action="{% url 'game:main' %}" not the login view, your form never gets handled.
You should point it to the same login view to handle the authentication, simply use action="." too keep it on the same URL as the login view or point it specifically using the same technique you're using already with main, i.e.
urlpatterns = patterns('',
url(r'^login/$', login_view, name='login'),
url(r'^main/$', main_view, name='main'),
)
And in your template:
action="{% url 'game:login' %}"