So I've got three users, a teacher, student, and admin. Both teacher and student users work fine but when I try to login using the admin form, it redirects to the student login form. I think it's because there's something wrong with the urls.py and the way the next parameter is configured but I'm not quite sure where to proceed.
Any help is much appreciated. Let me know if you need more information
Here are my admin views.py
#login_required
#admin_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'Your account has been updated!')
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)
main urls.py
urlpatterns = [
path('', classroom.home, name='home'),
path('students/', include(([
path('', students.QuizListView.as_view(), name='quiz_list'),
path('interests/', students.StudentInterestsView.as_view(), name='student_interests'),
path('taken/', students.TakenQuizListView.as_view(), name='taken_quiz_list'),
path('quiz/<int:pk>/', students.take_quiz, name='take_quiz'),
], 'classroom'), namespace='students')),
path('teachers/', include(([
path('', teachers.QuizListView.as_view(), name='quiz_change_list'),
path('quiz/add/', teachers.QuizCreateView.as_view(), name='quiz_add'),
path('quiz/<int:pk>/', teachers.QuizUpdateView.as_view(), name='quiz_change'),
path('quiz/<int:pk>/delete/', teachers.QuizDeleteView.as_view(), name='quiz_delete'),
path('quiz/<int:pk>/results/', teachers.QuizResultsView.as_view(), name='quiz_results'),
path('quiz/<int:pk>/question/add/', teachers.question_add, name='question_add'),
path('quiz/<int:quiz_pk>/question/<int:question_pk>/', teachers.question_change, name='question_change'),
path('quiz/<int:quiz_pk>/question/<int:question_pk>/delete/', teachers.QuestionDeleteView.as_view(), name='question_delete'),
], 'classroom'), namespace='teachers')),
path('admins/', include(([
path('', admins.profile, name='profile'),
], 'classroom'), namespace='admins')),
]
login urls.py
urlpatterns = [
path('', include('classroom.urls')),
path('accounts/', include('django.contrib.auth.urls')),
path('accounts/signup/', classroom.SignUpView.as_view(), name='signup'),
path('accounts/signup/student/', students.StudentSignUpView.as_view(), name='student_signup'),
path('accounts/signup/teacher/', teachers.TeacherSignUpView.as_view(), name='teacher_signup'),
path('accounts/signup/admin/', admins.register, name='register'),
]
signup form template
{% extends 'base.html' %}
{% load crispy_forms_tags %}
{% block content %}
<div class="row">
<div class="col-md-8 col-sm-10 col-12">
<h2>Sign up as a {{ user_type }}</h2>
<form method="post" novalidate>
{% csrf_token %}
<input type="hidden" name="next" value="{{ next }}">
{{ form|crispy }}
<button type="submit" class="btn btn-success">Sign up</button>
</form>
</div>
</div>
{% endblock %}
admin form template
{% extends "base.html" %}
{% load crispy_forms_tags %}
{% block content %}
<div class="content-section">
<form method="POST">
{% csrf_token %}
<fieldset class="form-group">
<input type="hidden" name="next" value="{{ next }}">
<legend class="border-bottom mb-4">Join Today</legend>
{{ form|crispy }}
</fieldset>
<div class="form-group">
<button class="btn btn-outline-info" type="submit">Sign Up</button>
</div>
</form>
<div class="border-top pt-3">
<small class="text-muted">
Already Have An Account? <a class="ml-2" href="{% url 'login' %}">Sign In</a>
</small>
</div>
</div>
{% endblock content %}
Try just removing #login_required from your profile view.
Since Django decorators work top-down, #login_required will kick in before #admin_required. But from https://pypi.org/project/django-simple-rest/:
admin_required simply makes sure that the user is logged in and is
also a super user before they will be granted access to the decorated
view method.
So, I think that #admin_required will already check if the user is logged in.
I've tried to add login form to my tasks web-app, but something goes wrong and I can't login to my created admin user. After click on the login button page just clearing up and my url changes to that. I have no idea how to fix it, help me please.
urls.py
urlpatterns = [
path('', TaskList.as_view(), name='tasks'),
path('login/', CustomLoginView.as_view(), name='login'),
path('logout/', LogoutView.as_view(next_page='login'), name='logout'),
path('task/<int:pk>', TaskDetail.as_view(), name='task'),
path('task-create/', TaskCreate.as_view(), name='task-create'),
path('task-edit/<int:pk>', TaskUpdate.as_view(), name='task-edit'),
path('task-delete/<int:pk>', TaskDelete.as_view(), name='task-delete'),
]
views.py
class CustomLoginView(LoginView):
template_name = 'base/login.html'
fields = '__all__'
redirect_authenticated_user = True
def get_success_url(self):
return reverse_lazy('tasks')
login.html
<h1>Login</h1>
<form metrhod="POST" action="">
{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="Login">
</form>
Could it possibly be a spelling error? metrhod="POST"
Try this:
<h1>Login</h1>
<form method="POST" action="">
{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="Login">
</form>
code skips the whole if block directly goes to the last else. I am using django.forms to get input from the user. the same thing happens when the method is set to GET. I tried the same with normal HTML forms the same result. But the weird fact it earlier It was working properly in the initial stages of the project while I was experimenting with my views and models this start causing the error in my project as I cannot get the user input.
views.py
def form(request):
form = InputForm()
return render(request, 'classifier/form.html', {'form':form})
def output(request):
print(request.POST) # returns empty dict
if request.method == "POST":
form = InputForm(request.POST)
if form.is_valid():
url = form.cleaned_data['input_url']
print(url)
return render(request, 'classifier/output.html', {'url':url})
else:
print(form.errors())
else:
print("error")
error = "Oops"
return render(request, 'classifier/output.html',{'url':error})
form.html
<form action="{% url 'classifier:output' %}" method="POST">
{% csrf_token %}
{% for non_field_error in form.non_field_error %}
<p class="help is-danger">{{ non_field_error}}</p>
{% endfor %}
{{ form }}
{% for error in form.erros %}
<p class="help is-danger">{{ error }}</p>
{% endfor %}
<div class="text-center">
<button type="button" class="btn btn-primary" id="btn" value='Save'>Submit</button>
</div>
</form>
urls.py
from django.urls import path
from . import views
app_name = 'classifier'
urlpatterns = [
path('', views.index, name='index'),
path('form/',views.form, name='form'),
path('output/',views.output, name='output'),
]
In your template:
<div class="text-center">
<button type="button" class="btn btn-primary" id="btn" value='Save'>Submit</button>
</div>
Submit button in reality is link: Submit
so there is a simple link following.
The corrected part of the code looks like this:
<div class="text-center">
<button type="submit" class="btn btn-primary" id="btn">Submit</button>
</div>
Im new to Django, and im trying to understand, why my code instead of redirect to :
http://127.0.0.1:8000/object/2/
redirect me to:
http://127.0.0.1:8000/object/2/?c=14
Where is the code, that adds this parameters?
Template:
{% if user.is_authenticated %}
{% get_comment_form for object as comment_form %}
<form action="{% comment_form_target %}" method="POST">
{% csrf_token %}
{{ comment_form.comment }}
{{ comment_form.content_type }}
{{ comment_form.object_pk }}
{{ comment_form.timestamp }}
{{ comment_form.security_hash }}
<input type="hidden" name="next" value="{{ object.get_absolute_url }}" />
<input type="submit" value="post comment" />
</form>
{% else %}
<p>Please log in to leave a comment.</p>
{% endif %}
views.py:
class realiz_photo_view(DetailView):
template_name = 'realization/realiz_photo.html'
model = realiz_photo
def get_context_data(self, **kwargs):
context = super(realiz_photo_view, self).get_context_data(**kwargs)
context["form"] = RealizationForm()
return context
urls.py:
url(r"^comments/", include("django.contrib.comments.urls")),
url(r'^object/', include('realization.urls')),
realization/urls.py:
urlpatterns = patterns('',
url(r'^(?P<pk>\d+)/$', realiz_photo_view.as_view()),
)
See my solution here: Django: Redirect to current article after comment post
It basically uses a view that's triggered by the comment post url which redirects back to the original referrer page.
How do you load both the Social Login, the Login form and Sign Up form to your Index page using django-allauth?
Something similar like when you go to facebook.com.
accounts/url are already working and I've tried copying the
<form class="login" method="POST" action="{% url 'account_login' %}">
{% csrf_token %}
{{ form.as_p }}
{% if redirect_field_value %}
<input type="hidden" name="{{ redirect_field_name }}" value="{{ redirect_field_value }}" />
{% endif %}
<a class="button secondaryAction" href="{% url 'account_reset_password' %}">{% trans "Forgot Password?" %}</a>
<button class="primaryAction" type="submit">{% trans "Sign In" %}</button>
</form>
to my index.html but it doesn't work.
I'm new to Python Programming and Django development but i've done some excerise with tutorials in the Django Book.
The view that handles your 'index' url and renders your index.html template has to have a login form, for that you have to make it a FormView descendant, and set the class attribute to LoginForm (allauth's login form). Otherwise, you can't render {{form.as_p}} to the template (because there is no form in your context).