So, lets start the now:
lets start with surrounding first: i am trying to create owner and staff for as multiple users , say owner can only create user and owner can be created by super users only , for such thing we need to have multiple logins access i.e login for owner and staff along with signup also,
now for this , lets create new app named account:
register the created app inside settings.py of the project
and inside urls.py of the project :
path('account/', include('account.urls')),
now, inside urls.py of account app
from django.contrib import admin
from django.urls import path
from django.conf.urls import url, include
from django.conf.urls.static import static
from .import views
urlpatterns = [
path('hotelowner/', views.HotelOwnerSignUpView.as_view(), name="hotelowner_signup"),
#path('hotelowner/', views.signup, name="hotelowner_signup"),
path('hotelstaff/', views.HotelStaffSignUpView.as_view(), name="hotelstaff_signup"),
]
Main important section is models.py of the account app where we are going to overwrite Abstractclass of django default auth to add more fields on the form
from django.db import models
from django.contrib.auth.models import AbstractUser
class User(AbstractUser):
email=models.EmailField(
verbose_name='email address',
max_length=255,
unique=True,
)
is_hotel_staff=models.BooleanField(default=False)
is_hotel_owner=models.BooleanField(default=False)
form here we create our own user where all default feature of Abstract class is included like : username ,password, firstname etc. along with our customized field is_hotel_staff , is_hotel_owner
now , lets make forms.py of the account app:
from django import forms
from django.contrib.auth.forms import UserCreationForm
from django.db import transaction
from account.models import User
from hotel.owner.models import HotelOwner
from hotel.staff.models import HotelStaff
class HotelOwnerSignUpForm(UserCreationForm):
email=forms.EmailField(required=True,label='Email')
first_name=forms.CharField(required=True,label='First Name')
last_name=forms.CharField(required=True,label='Last Name')
class Meta(UserCreationForm.Meta):
model=User
fields=("first_name","last_name","email","username","password1","password2")
@transaction.atomic
def save(self):
user=super().save(commit=False)
user.is_hotel_owner=True
user.save()
owner=HotelOwner.objects.create(user=user)
return user
class HotelStaffSignUpForm(UserCreationForm):
class Meta(UserCreationForm.Meta):
model=User
fields=("first_name","last_name","email","username","password1","password2")
# @transaction.atomic
# def save(self):
# user=super().save(commit=False)
# user.is_hotel_staff=True
# user.save()
# staff=HotelStaff.objects.create(user=user)
# return user
Here,
we store general information to the Users table and also store the user id just been created to the hotel owners table so that we can identify this one is the hotel ownera nd we can update extra information:
for more clearity lets see what is there in hotel owner model.py:
from account.models import User
class HotelOwner(models.Model):
name = models.CharField(max_length=80,null=True)
contact = models.BigIntegerField(null=True)
# email = models.EmailField(unique=True,null=True)
# password = models.CharField(max_length = 30,null=True)
image = models.ImageField(default='default.png')
address = models.CharField(max_length=80,null=True)
created_at = models.DateTimeField(default=datetime.now, blank=True)
user = models.OneToOneField(User, on_delete=models.CASCADE, primary_key=True)
here, we import user form account model, because now our default user is user created from accounts app, and also we make that user as primary key .
also see the forms.py of owner for more clearity
from django import forms
from ..models import Hotels
from .models import HotelOwner
class HotelOwnerForm(forms.ModelForm):
class Meta:
model = HotelOwner
fields = ["name","contact","image","address","created_at"]
here, we haven't included user_id field in fields because we will not create input field for the user_id we obtain that directly after username and password and other general information about the user is stored in account.users table previously.
Now its time to go deep towards views.py of account app, where there is major functioning
from django.shortcuts import render
from django.shortcuts import redirect
from django.views.generic import CreateView
from .forms import HotelOwnerSignUpForm
from .forms import HotelStaffSignUpForm
from django.http import HttpResponse
from account.models import User
from hotel.owner.models import HotelOwner
class HotelOwnerSignUpView(CreateView):
model = User
form_class = HotelOwnerSignUpForm
template_name = 'account/signup_form.html'
def form_valid(self, form):
user = form.save()
login(self.request, user)
user.save()
id=user.id
return redirect('hotel:ownerupdate',id)
class HotelStaffSignUpView(CreateView):
model = User
form_class = HotelStaffSignUpForm
template_name = 'account/signup_form.html'
# print(request.user)
def form_valid(self, form):
# user = form.save()
user=form.save(commit=False)
user.is_hotel_staff=True
user.save()
owner_id=self.request.user.id
staff=HotelStaff.objects.create(user=user,owner_id_id=owner_id)
id=user.id
return redirect('hotel:staffupdate',id)
after storing user in account_users table and storing user_id inside owners table, first the created user will be logged in to the system then will redirect to the update function of the owner so that we can add general information to the owners profile or say update owners detail.
let me explain about namespace mathod used in the system:
return redirect('hotel:ownerupdate',id)
here hotel:ownerupdate refers to the updatefunction of the owner module which is included inside hotel app ursl.py i.e.
# urls.py of hotel app
app_name='hotel'
urlpatterns = [
path('owner/', include('hotel.owner.urls')),
]
# urls.py of owner module of hotel app
path('update/<int:pk>', views.OwnerUpdate.as_view(), name="ownerupdate"),
now lets see the signup_forms.html inside of account app template:
{% extends 'travel/sign_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 %}
for using 'crispy_forms'
install django-crispy-forms-1.7.2 in your environment and then include the in installed app thats all you need to do ,
and include crispy template pack also inside settings.py i.e:
CRISPY_TEMPLATE_PACK='bootstrap4'
since we are customizing everything so, lets make one small costumization for our easyness : i.e make out own login form, logout and our own redirect path after login , logout etc, for that just write following lines of codes inside settings.py
AUTH_USER_MODEL='account.User'
LOGIN_URL='login'
LOGOUT_URL='logout'
LOGIN_REDIRECT_URL='urltoredirect'
LOGOUT_REDIRECT_URL='login'
- we set auth user model which was default user model of python to our user of account app
- login url to login which will understand as login.html of registration template which will be override by our custom register template's login.html .
- after logout we redirect to login.html again
Now, lets create registration folder inside templates folder of the project
login.html
{% extends 'travel/sign_base.html' %}
{% load crispy_forms_tags %}
{% block content %}
{% if form.non_field_errors %}
<div class="alert alert-danger alert-dismissible fade show" role="alert">
{% for error in form.non_field_errors %}
<p{% if forloop.last %} class="mb-0"{% endif %}>{{ error }}</p>
{% endfor %}
<button type="button" class="close" data-dismiss="alert" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
{% endif %}
<div class="row">
<div class="col-lg-4 col-md-6 col-sm-8 col-12">
<h2>Log in</h2>
<form method="post" novalidate>
{% csrf_token %}
<input type="hidden" name="next" value="{{ next }}">
{{ form.username|as_crispy_field }}
{{ form.password|as_crispy_field }}
<button type="submit" class="btn btn-primary">Log in</button>
</form>
</div>
</div>
{% endblock %}
For logout :
<a class="nav-link" href="{%url 'logout' %}"> Logout</a>
on clicking the logout button with above url it will destroy the session and will be logged out automatically and redirect to the url that you have specified above.
Finally , you have come this way long and completed multple authentication for multiple user
THANK YOU FOR SUPPORT AND TRUST :
If any problems occured while following this steps you cam comment below and get direct support form me
thank you for this helpfull post sir,
ReplyDelete