Setting Up Logins For Users with Django - django

I am trying to use Django's built in user authentication for login/allowing users to create an account and login. I think there's something wrong with my urls or where files are placed in the project. Can anyone help?
I know the login.html file is supposed to be inside a folder called 'registration.' I think the fact that my templates are then in a sub folder called 'capstone' might be causing issues. I just don't know how to point to the right file when someone clicks to login.
In urls.py under 'weather' I have the following. In two tutorials I saw it should say 'accounts/' but I'm a bit confused as to why.
urlpatterns = [
path('admin/', admin.site.urls),
path('', include('capstone.urls')), # medium site says to do this
path('accounts/', include('django.contrib.auth.urls')),
] + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
This is how my files are set up in Visual Studio Code:
Now under weather, I have:
Now under urls.py under capstone, I have:
router = routers.DefaultRouter()
router.register(r'locations', views.LocationViewSet)
urlpatterns = [
path('accounts/', include('django.contrib.auth.urls')),
path('api-auth/', include('rest_framework.urls',
namespace='rest_framework')),
path("", views.home, name="home"),
path("register", views.register, name="register"),
path("login", views.login_view, name="login"),
] + static(settings.STATIC_URL,
document_root=settings.STATIC_ROOT)
urlpatterns += static(settings.STATIC_URL,
document_root=settings.STATIC_ROOT)
urlpatterns += static(settings.MEDIA_URL,
document_root=settings.MEDIA_ROOT)
views.py:
def home(request):
return render(request, "capstone/home.html")
def login_view(request):
if request.method == "POST":
email = request.POST["email"]
password = request.POST["password"]
user = authenticate(request, username=email,
password=password)
# Check if authentication successful
if user is not None:
login(request, user)
return HttpResponseRedirect(reverse('home'))
else:
return render(request, "capstone/login.html", {
"message": "Invalid email and/or password."
})
else:
return render(request, "capstone/login.html")
def register(request):
if request.method == "POST":
email = request.POST["email"]
# Ensure password matches confirmation - this part works!
password = request.POST["password"]
confirmation = request.POST["confirmation"]
if password != confirmation:
return render(request, "capstone/signup.html", {
"message": "Passwords must match."
})
# Attempt to create new user
try:
User = get_user_model()
user = User.objects.create_user(email, email,
password)
user.save()
except IntegrityError as e:
print(e)
return render(request, "capstone/signup.html", {
"message": "Email address already taken."
})
login(request, user)
return HttpResponseRedirect(reverse("home"))
else:
return render(request, "capstone/signup.html")

Setting the path to accounts/ allows you to create a url such as <your_site_name>/accounts/login
https://docs.djangoproject.com/en/3.2/topics/auth/default/#module-django.contrib.auth.views
Basicaly the link shows you get the login/, logout/, and a bunch other urls/views for free. You can append names to the url making it longer if you would like...
Now Im not sure which app the url_conf is in, that calls path('accounts/', include('django.contrib.auth.urls')), but I'm guessing since you have the static_dir addition at the bottom, its the weather/settings.py urls conf.
In settings.py in the TEMPLATES settings. If APP_DIRS is True, (which is by default), Django will check the template directory which is inside app directory that the template is being called in. In your case, it will check the template directory in the weather app (which is your main app). You would need to change your directory heiarchy.
Using django.contrib.auth urls
weather
|
|--templates
|
|--registration
|
|--login.html
If you want to use the capstone app. Then you need to move the call
path('accounts/', include('django.contrib.auth.urls')) to the capstone app. At which point the URL will change to <your_site_name/capstone/accounts/login>.
=============================
Now you have a login_view instead, named login which is overriding the login view of django contrib, so your heirachy should resemble something like this.
capstone
|
|--templates
|
|--capstone
|
| -- login.html
Also FYI make sure to end your paths to the URL’s with “/“. Like “login” should be “login/“

Related

Django TemplateDoesNotExist, when trying to redirect user's

I have this structure,and basically what I want is to send the user to the right place depending on their group.
myproject/
|-- myproject
|--urls.py
|--settings.py
|--views.py
|-- pluviais/
|--urls.py
|--views.py
|-- eletricistas/
|--urls.py
|--views.py
So when they login, my settings.py redirect to index, (LOGIN_REDIRECT_URL = 'index')
myproject/urls.py
from .views import index
urlpatterns = [
path('', views.index, name='index'),
path('admin/', admin.site.urls),
path('login/', auth_views.LoginView.as_view(template_name='login.html'), name='login'),
path('logout/', auth_views.LogoutView.as_view(), name='logout'),
path('pluviais/', include('pluviais.urls')),
path('eletricistas/', include('eletricistas.urls')),
]
document_root=settings.MEDIA_ROOT)
myproject/views.py
from django.contrib.auth.models import Group,User
from django.shortcuts import render, redirect
def index(request):
users_in_group = Group.objects.get(name="tablet").user_set.all()
if request.user in users_in_group:
user_responsaveis_pluviais = User.objects.filter(username=request.user, groups__name='Responsáveis - pluviais').exists()
user_chefes_pluviais = User.objects.filter(username=request.user, groups__name='Chefes - pluviais').exists()
print(user_responsaveis_pluviais)
if user_responsaveis_pluviais == True or user_chefes_pluviais==True:
return render(request, 'intervencao')
else:
return render(request, 'tarefas')
As you can see the idea is simply depending on the groups that the users are in, they are redirected to the right place ( or go to pluviais/ or eletricistas/
pluviais/urls.py
urlpatterns = [
path('tablet', views.intervencao, name='intervencao'),
]
eletricistas/urls.py
urlpatterns = [
path('tablet', views.tarefas, name='tarefas'),
]
the problem is that always giving me the error TemplateDoesNotExist at /, so maybe i am doing this wrong.
render() is a django function that takes a request object AND a template (HTML) path.
You need a templates directory in the base project, and inside that folder you need to create an HTML file.
Then, your view code could read:
return render(request, 'pluviais.html')
or
return render(request, 'electricistas.html')
def index(request):
users_in_group = Group.objects.get(name="tablet").user_set.all()
if request.user in users_in_group:
user_responsaveis_pluviais = User.objects.filter(username=request.user, groups__name='Responsáveis - pluviais').exists()
user_chefes_pluviais = User.objects.filter(username=request.user, groups__name='Chefes - pluviais').exists()
user_responsaveis_eletricistas = User.objects.filter(username=request.user, groups__name='Responsáveis - eletricistas').exists()
print(user_responsaveis_pluviais)
print(user_responsaveis_eletricistas)
if user_responsaveis_pluviais == True or user_chefes_pluviais==True:
return HttpResponseRedirect(reverse('intervencao'))
elif user_responsaveis_eletricistas ==True:
return HttpResponseRedirect(reverse('tarefas'))
else:
return HttpResponseRedirect('/admin')
basically what I was needed was from HttpResponseRedirect(reverse())

Reverse for 'detail' with arguments '('accounts/<int:pk>/',)' not found. 1 pattern(s) tried: ['accounts/(?P<pk>[0-9]+)/$']

In my blog, i want when someone clicks on read more, it should direct the person to the log in page, which is working fine, then after inputting the log in credentials, it should take the person to the detail page and this where I'm getting the error above.
this is the code
urls.py
from . import views
from django.urls import path
from.views import Home, Detail, CreatePost
urlpatterns = [
path('', Home.as_view(), name='home'),
path('register/', views.register, name='register'),
path('login/', views.login, name='login'),
path('logout/', views.logout, name='logout'),
path('post/', CreatePost.as_view(success_url='/'), name='post'),
path('accounts/<int:pk>/', Detail.as_view(), name='detail'),
]
The line below is from the entry_list.html
Read More →
Then below is my login logic
```
def login(request):
if request.method == 'POST':
username = request.POST['username']
password = request.POST['password']
user = auth.authenticate(username=username, password=password)
if user is not None:
auth.login(request, user)
return redirect('detail', 'accounts/<int:pk>/')
else:
return redirect('login')
else:
return render(request, 'login.html')
```
path('accounts/<int:pk>/', Detail.as_view(), name='detail')
In that url definition, <int:pk> is a placeholder for the user id; it is not literally part of the url.
To redirect to the url, you must supply the user id:
return redirect('detail', pk=user.id)

Reverse for 'index' not found. 'index' is not a valid view function or pattern name

I have a simple return HttpResponseRedirect(reverse('index')) where 'index' is the name of the view. on running the server the index view is correctly displayed but gives out this error "NoReverseMatch at /vehicle_movement/checkinview"on redirecting.
I was working on django 1.1 for the same project but switched to django 2.2 later. Redirect was working fine with url django 1.1 but gives this error with path django 2.2. Another change that i have done is earlier in 1.1 project the index view url was written in the main url.py but now it is written in the apps urls.py.
This is views.py
def index(request):
return render(request,'vehicle_movement/index.html',{})
def CheckinView(request):
if request.method == "POST":
checkin_form = CheckinForm(data = request.POST)
if checkin_form.is_valid():
checkin_form.save()
return HttpResponseRedirect(reverse('index'))
else:
HttpResponse("Error")
else:
checkin_form = CheckinForm()
return render(request,'vehicle_movement/checkin.html',{'checkin_form':checkin_form})
This is the Main urls.py
urlpatterns = [
path('admin/', admin.site.urls),
path('', include(('vehicle_movement.urls','vehicle_movement'),namespace = 'vehicle_movement')),
]
This is app urls.py
app_name = 'vehicle_movement'
urlpatterns = [
path('', views.index, name='index'),
path('index', views.index, name='index'),
]
This is the structure
Warehouse
-Warehouse
-init.py
-settings.py
-urls.py
-static
-templates
-vehicle_movement
-urls.py
-views.py
The TEMPLATES_DIR
TEMPLATES_DIR = os.path.join(BASE_DIR,'templates')
``
You've namespaced your app urls, so you need to use that namespace when reversing them:
reverse('vehicle_movement:index')
But you've also got two paths with the same name in your app urls, which will cause conflicts, if not an error. Delete one of them.
Check name="htmlfilename" in app urls is correct or not.

Django LOGIN_REDIRECT_URL failing when redirecting to the users profile

I'm using django-registration-redux and have most of it working. I'm trying to redirect to the user profile after login. Currently the URL for user profile is:
url(r'^user/(\w+)/$', views.profile, name='profile'),
...and the view for the profile is:
def profile(request, username):
user = get_object_or_404(User, username=username)
products = Product.objects.filter(user=user)
if not request.user == user:
return render(request, 'no.html')
else:
return render(request, 'profile.html', {'user':user,'products': products})
I've added LOGIN_REDIRECT_URL = 'profile' to settings.py but am getting the error:
Reverse for 'profile' with no arguments not found. 1 pattern(s) tried: ['user/(\\w+)/$']
I've gone around this so many times I'm totally confused. I could simply set LOGIN_REDIRECT_URL = 'home' and be done with it, but then I wouldn't have gotten past this error. Do I need to create a different view for this?
EDIT:
If I set LOGIN_REDIRECT_URL to 'home' or 'products' or any other URL it works - just not for 'profile'. Here's my urls.py:
urlpatterns = [
url(r'^$', views.HomePage.as_view(), name='home'),
url(r'^contact/$', views.contact, name='contact'),
url(r'^designers/', views.DesignersView.as_view(), name='designers'),
url(r'^subscribe/$', views.subscribe, name='subscribe'),
url(r'^products/$', views.products, name = 'products'),
url(r'^product/$', ProductListView.as_view(), name='product_list'),
url(r'^user/(\w+)/$', views.profile, name='profile'),
url(r'post_url/', views.post_product, name='post_product'),
url(r'^([0-9]+)/$', views.detail, name = 'detail'),
url(r'^like_product/$', views.like_product, name='like_product' ),
url(r'^profile/edit/$', views.edit_profile, name='edit_profile'),
url(r'^(?P<pk>\d+)/edit/$', PostUpdateView.as_view(), name='product-edit'),
url(r'^(?P<pk>\d+)/delete/$', PostDeleteView.as_view(), name='product-delete'),
]
I'm still searching - just not finding a solution, yet.
Finally found a way to do this. I created a login view in my views.py:
from django.contrib.auth.views import LoginView
class LoginView(LoginView):
def get_success_url(self):
return reverse('profile', args=[self.request.user.username])
Also added this to my urls.py to reflect the new view:
url(r'^accounts/login/$', LoginView.as_view(), name='login'),
Removed LOGIN_REDIRECT_URL from settings.py and it worked.
Your regex url isn't correct. Change:
url(r'^user/(\w+)/$', views.profile, name='profile'),
To
url(r'^user/(?P<username>[\w\-]+)/$', views.profile, name='profile'),

Django keeps showing loggin form after being logged in

In a Django project I am using the standard authentication system. The user is redirected to /bewerken/dashboard/, which has two links. One of them is linked to /bewerken/inhoud/. However, when clicking the link, the login form is shown again (at url /bewerken/inhoud/). So, the user logs in and is returnd to /bewerken/dashboard again (because that is the 'next' url). And on and on. Don't know what I'm doing wrong!
The urls.py from the project:
urlpatterns = patterns('',
url(r'^admin/', include(admin.site.urls)),
url(r'^bewerken/', include('zzpwebsites.apps.user.urls')),
)
The urls.py from the app:
urlpatterns = patterns('',
url(r'^inhoud/$', views.bewerken_inhoud, name='bewerken_inhoud'),
url(r'^dashboard/$', views.dashboard, name='dashboard'),
url(r'^', 'django.contrib.auth.views.login', {'template_name': 'user/inloggen.html'}),
)
And the view:
#login_required
def bewerken_inhoud(request):
Usp_1 = Usp.objects.filter(user=request.user)
context = ({'usp_1': usp_1,})
return render(request, 'user/bewerken_inhoud.html' , context)
Thanks!