Preparing files for admin profiles
Changing File models to allow user association
This commit is contained in:
parent
8eab735bd8
commit
53780751d1
12 changed files with 411 additions and 62 deletions
15
core/forms/profiles.py
Normal file
15
core/forms/profiles.py
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
from django.forms import ModelForm, CharField, EmailField
|
||||||
|
from django.contrib.auth import get_user_model
|
||||||
|
from django.utils.translation import gettext_lazy as _
|
||||||
|
|
||||||
|
from core.models import AdminProfile
|
||||||
|
|
||||||
|
class AdminEditForm(ModelForm):
|
||||||
|
#fields from User model that you want to edit
|
||||||
|
first_name = CharField(required=True, label=_('First Name'))
|
||||||
|
last_name = CharField(required=True, label=_('Last Name'))
|
||||||
|
email = EmailField(required=True, labels=_("Email Address"))
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
model = AdminProfile
|
||||||
|
fields = ('first_name', 'last_name', "email", 'mobile', "role", "image")
|
|
@ -1,13 +1,31 @@
|
||||||
from django.db.models import Model, CharField, ImageField, FileField
|
from django.db.models import Model, CharField, ImageField, FileField, ManyToManyField, ForeignKey, BooleanField, CASCADE
|
||||||
|
from django.contrib.auth import get_user_model
|
||||||
|
|
||||||
|
from polymorphic.models import PolymorphicModel
|
||||||
|
|
||||||
from core.helpers.files import generate_storage_filename
|
from core.helpers.files import generate_storage_filename
|
||||||
|
from core.models.profiles import Profile
|
||||||
|
|
||||||
# Create your models here.
|
# Create your models here.
|
||||||
|
|
||||||
class ImageFile(Model):
|
class BaseFile(PolymorphicModel):
|
||||||
filename = CharField(max_length=255)
|
filename = CharField(max_length=255)
|
||||||
file = ImageField(upload_to=generate_storage_filename)
|
|
||||||
|
|
||||||
class File(Model):
|
class ImageFile(BaseFile):
|
||||||
filename = CharField(max_length=255)
|
rawfile = ImageField(upload_to=generate_storage_filename)
|
||||||
file = FileField(upload_to=generate_storage_filename)
|
|
||||||
|
@property
|
||||||
|
def get_file(self):
|
||||||
|
return self.image
|
||||||
|
|
||||||
|
class File(BaseFile):
|
||||||
|
rawfile = FileField(upload_to=generate_storage_filename)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def get_file(self):
|
||||||
|
return self.file
|
||||||
|
|
||||||
|
class FileAssociation(Model):
|
||||||
|
file = ForeignKey(BaseFile, CASCADE)
|
||||||
|
user = ForeignKey(get_user_model(), CASCADE)
|
||||||
|
visible = BooleanField()
|
|
@ -3,16 +3,52 @@ import importlib
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.urls import path
|
from django.urls import path
|
||||||
|
|
||||||
from core.views import DashboardView, LoginView, OTPSelectorView, LogoutView, OTPValidatorView, BackendNotImplementedView
|
from core.views import (
|
||||||
|
DashboardView,
|
||||||
|
LoginView,
|
||||||
|
OTPSelectorView,
|
||||||
|
LogoutView,
|
||||||
|
OTPValidatorView,
|
||||||
|
BackendNotImplementedView,
|
||||||
|
AdminListView,
|
||||||
|
AdminDeleteView,
|
||||||
|
AdminEditView,
|
||||||
|
AdminCreateView,
|
||||||
|
DBSettingsListView,
|
||||||
|
DBSettingsEditView,
|
||||||
|
DBSettingsDeleteView,
|
||||||
|
DBSettingsCreateView,
|
||||||
|
)
|
||||||
|
|
||||||
URLPATTERNS = [
|
URLPATTERNS = []
|
||||||
path('login/', LoginView.as_view(), name="login"),
|
|
||||||
path('login/otp/select/', OTPSelectorView.as_view(), name="otpselector"),
|
# Auth URLs
|
||||||
path('login/otp/validate/', OTPValidatorView.as_view(), name="otpvalidator"),
|
|
||||||
path('logout/', LogoutView.as_view(), name="logout"),
|
URLPATTERNS.append(path('login/', LoginView.as_view(), name="login"))
|
||||||
path('admin/', DashboardView.as_view(), name="dashboard"),
|
URLPATTERNS.append(path('login/otp/select/', OTPSelectorView.as_view(), name="otpselector"))
|
||||||
path('admin/oops/', BackendNotImplementedView.as_view(), name="backendni")
|
URLPATTERNS.append(path('login/otp/validate/', OTPValidatorView.as_view(), name="otpvalidator"))
|
||||||
]
|
URLPATTERNS.append(path('logout/', LogoutView.as_view(), name="logout"))
|
||||||
|
|
||||||
|
# Base Backend URLs
|
||||||
|
|
||||||
|
URLPATTERNS.append(path('admin/', DashboardView.as_view(), name="dashboard"))
|
||||||
|
URLPATTERNS.append(path('admin/oops/', BackendNotImplementedView.as_view(), name="backendni"))
|
||||||
|
|
||||||
|
# Backend Database Settings URLs
|
||||||
|
|
||||||
|
URLPATTERNS.append(path("admin/dbsettings/", DBSettingsListView.as_view(), name="dbsettings"))
|
||||||
|
URLPATTERNS.append(path("admin/dbsettings/<pk>/delete/", DBSettingsDeleteView.as_view(), name="dbsettings_delete"))
|
||||||
|
URLPATTERNS.append(path("admin/dbsettings/<pk>/edit/", DBSettingsEditView.as_view(), name="dbsettings_edit"))
|
||||||
|
URLPATTERNS.append(path("admin/dbsettings/create/", DBSettingsCreateView.as_view(), name="dbsettings_create"))
|
||||||
|
|
||||||
|
# Backend User Administration URLs
|
||||||
|
|
||||||
|
URLPATTERNS.append(path('admin/profiles/', AdminListView.as_view(), name="admins"))
|
||||||
|
URLPATTERNS.append(path("admin/profiles/<pk>/delete/", AdminDeleteView.as_view(), name="admins_delete"))
|
||||||
|
URLPATTERNS.append(path("admin/profiles/<pk>/edit/", AdminEditView.as_view(), name="admins_edit"))
|
||||||
|
URLPATTERNS.append(path("admin/profiles/create/", AdminCreateView.as_view(), name="admins_create"))
|
||||||
|
|
||||||
|
# External Module URLs
|
||||||
|
|
||||||
for module in settings.EXPEPHALON_MODULES:
|
for module in settings.EXPEPHALON_MODULES:
|
||||||
try:
|
try:
|
||||||
|
@ -21,12 +57,3 @@ for module in settings.EXPEPHALON_MODULES:
|
||||||
URLPATTERNS.append(path(f'admin/modules/{module}/{url}', action, name=f"{module}_{name}"))
|
URLPATTERNS.append(path(f'admin/modules/{module}/{url}', action, name=f"{module}_{name}"))
|
||||||
except (AttributeError, ModuleNotFoundError):
|
except (AttributeError, ModuleNotFoundError):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
try:
|
|
||||||
from core.views import DBSettingsListView, DBSettingsEditView, DBSettingsDeleteView, DBSettingsCreateView
|
|
||||||
URLPATTERNS.append(path("admin/dbsettings/", DBSettingsListView.as_view(), name="dbsettings"))
|
|
||||||
URLPATTERNS.append(path("admin/dbsettings/<pk>/delete/", DBSettingsDeleteView.as_view(), name="dbsettings_delete"))
|
|
||||||
URLPATTERNS.append(path("admin/dbsettings/<pk>/edit/", DBSettingsEditView.as_view(), name="dbsettings_edit"))
|
|
||||||
URLPATTERNS.append(path("admin/dbsettings/create/", DBSettingsCreateView.as_view(), name="dbsettings_create"))
|
|
||||||
except:
|
|
||||||
pass
|
|
0
core/receivers/__init__.py
Normal file
0
core/receivers/__init__.py
Normal file
7
core/receivers/profiles.py
Normal file
7
core/receivers/profiles.py
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
from django.db.models.signals import post_delete
|
||||||
|
|
||||||
|
from core.models.profiles import AdminProfile
|
||||||
|
|
||||||
|
@receiver(post_delete, sender=AdminProfile)
|
||||||
|
def delete_user(sender, instance, *args, **kwargs):
|
||||||
|
instance.user.delete()
|
|
@ -4,6 +4,7 @@ from django.conf import settings
|
||||||
|
|
||||||
from core.views.dbsettings import *
|
from core.views.dbsettings import *
|
||||||
from core.views.auth import *
|
from core.views.auth import *
|
||||||
|
from core.views.profiles import *
|
||||||
|
|
||||||
# Create your views here.
|
# Create your views here.
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,6 @@ from django.conf import settings
|
||||||
from django.views.generic import ListView, UpdateView, DeleteView, CreateView
|
from django.views.generic import ListView, UpdateView, DeleteView, CreateView
|
||||||
from django.urls import reverse_lazy
|
from django.urls import reverse_lazy
|
||||||
|
|
||||||
try:
|
|
||||||
from dbsettings.models import Setting
|
from dbsettings.models import Setting
|
||||||
|
|
||||||
class DBSettingsListView(ListView):
|
class DBSettingsListView(ListView):
|
||||||
|
@ -45,6 +44,3 @@ try:
|
||||||
context = super().get_context_data(**kwargs)
|
context = super().get_context_data(**kwargs)
|
||||||
context["title"] = "Create Setting"
|
context["title"] = "Create Setting"
|
||||||
return context
|
return context
|
||||||
|
|
||||||
except ModuleNotFoundError:
|
|
||||||
pass
|
|
||||||
|
|
47
core/views/profiles.py
Normal file
47
core/views/profiles.py
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
from django.conf import settings
|
||||||
|
from django.views.generic import FormView, ListView, DeleteView
|
||||||
|
from django.urls import reverse_lazy
|
||||||
|
from django.contrib.auth import get_user_model
|
||||||
|
|
||||||
|
from core.models import AdminProfile
|
||||||
|
|
||||||
|
class AdminListView(ListView):
|
||||||
|
template_name = f"{settings.EXPEPHALON_BACKEND}/profiles/index.html"
|
||||||
|
model = AdminProfile
|
||||||
|
|
||||||
|
def get_context_data(self, **kwargs):
|
||||||
|
context = super().get_context_data(**kwargs)
|
||||||
|
context["title"] = "Administrator Users"
|
||||||
|
return context
|
||||||
|
|
||||||
|
class AdminEditView(FormView):
|
||||||
|
template_name = f"{settings.EXPEPHALON_BACKEND}/profiles/update.html"
|
||||||
|
model = get_user_model()
|
||||||
|
success_url = reverse_lazy("dbsettings")
|
||||||
|
fields = ["key", "value"]
|
||||||
|
|
||||||
|
def get_context_data(self, **kwargs):
|
||||||
|
context = super().get_context_data(**kwargs)
|
||||||
|
context["title"] = "Edit Setting"
|
||||||
|
return context
|
||||||
|
|
||||||
|
class AdminDeleteView(DeleteView):
|
||||||
|
template_name = f"{settings.EXPEPHALON_BACKEND}/profiles/delete.html"
|
||||||
|
model = get_user_model()
|
||||||
|
success_url = reverse_lazy("dbsettings")
|
||||||
|
|
||||||
|
def get_context_data(self, **kwargs):
|
||||||
|
context = super().get_context_data(**kwargs)
|
||||||
|
context["title"] = "Delete Administrator"
|
||||||
|
return context
|
||||||
|
|
||||||
|
class AdminCreateView(FormView):
|
||||||
|
template_name = f"{settings.EXPEPHALON_BACKEND}/profiles/create.html"
|
||||||
|
model = get_user_model()
|
||||||
|
success_url = reverse_lazy("dbsettings")
|
||||||
|
fields = ["key", "value"]
|
||||||
|
|
||||||
|
def get_context_data(self, **kwargs):
|
||||||
|
context = super().get_context_data(**kwargs)
|
||||||
|
context["title"] = "Create Setting"
|
||||||
|
return context
|
57
templates/backend/profiles/create.html
Normal file
57
templates/backend/profiles/create.html
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
{% extends "backend/base.html" %}
|
||||||
|
{% load bootstrap4 %}
|
||||||
|
{% block content %}
|
||||||
|
<div class="app-page-title">
|
||||||
|
<div class="page-title-wrapper">
|
||||||
|
<div class="page-title-heading">
|
||||||
|
<div class="page-title-icon">
|
||||||
|
<i class="fa fa-users-cog">
|
||||||
|
</i>
|
||||||
|
</div>
|
||||||
|
<div>Administrator Users - Create User
|
||||||
|
<div class="page-title-subheading">Create a new administrator
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="page-title-actions">
|
||||||
|
<button type="button" data-toggle="tooltip" title="New Setting" data-placement="bottom" class="btn-shadow mr-3 btn btn-success">
|
||||||
|
<i class="fa fa-plus"></i> New Administrator
|
||||||
|
</button>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-12 col-lg-0">
|
||||||
|
<div class="mb-3 card">
|
||||||
|
<div class="card-header-tab card-header-tab-animation card-header">
|
||||||
|
<div class="card-header-title">
|
||||||
|
<i class="header-icon lnr-apartment icon-gradient bg-love-kiss"> </i>
|
||||||
|
Create Administrator
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="card-body">
|
||||||
|
<div class="tab-content">
|
||||||
|
<div class="tab-pane fade show active" id="tabs-eg-77">
|
||||||
|
<form method="POST">
|
||||||
|
{% csrf_token %}
|
||||||
|
{% bootstrap_form form %}
|
||||||
|
{% buttons %}
|
||||||
|
<button type="submit" class="btn-shadow mr-3 btn btn-success">
|
||||||
|
<i class="fa fa-check"></i> Save
|
||||||
|
</button>
|
||||||
|
<a href="{% url "dbsettings" %}" class="btn-shadow mr-3 btn btn-danger">
|
||||||
|
<i class="fa fa-times"></i> Cancel
|
||||||
|
</a>
|
||||||
|
{% endbuttons %}
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
{% endblock %}
|
57
templates/backend/profiles/delete.html
Normal file
57
templates/backend/profiles/delete.html
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
{% extends "backend/base.html" %}
|
||||||
|
{% load bootstrap4 %}
|
||||||
|
{% block content %}
|
||||||
|
<div class="app-page-title">
|
||||||
|
<div class="page-title-wrapper">
|
||||||
|
<div class="page-title-heading">
|
||||||
|
<div class="page-title-icon">
|
||||||
|
<i class="fa fa-database">
|
||||||
|
</i>
|
||||||
|
</div>
|
||||||
|
<div>Administrator Users - Delete User
|
||||||
|
<div class="page-title-subheading">Delete an administrator from the system
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="page-title-actions">
|
||||||
|
<button type="button" data-toggle="tooltip" title="New Administrator" data-placement="bottom" class="btn-shadow mr-3 btn btn-success">
|
||||||
|
<i class="fa fa-plus"></i> New Administrator
|
||||||
|
</button>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-12 col-lg-0">
|
||||||
|
<div class="mb-3 card">
|
||||||
|
<div class="card-header-tab card-header-tab-animation card-header">
|
||||||
|
<div class="card-header-title">
|
||||||
|
<i class="header-icon lnr-apartment icon-gradient bg-love-kiss"> </i>
|
||||||
|
Deleting {{ object.user.username }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="card-body">
|
||||||
|
<div class="tab-content">
|
||||||
|
<div class="tab-pane fade show active" id="tabs-eg-77">
|
||||||
|
<form method="POST">
|
||||||
|
{% csrf_token %}
|
||||||
|
Are you sure you wish to delete {{ object.user.username }}? This will irrevocably delete their account and any associated information. You can also disable the user without deleting their data!
|
||||||
|
{% buttons %}
|
||||||
|
<button type="submit" class="btn-shadow mr-3 btn btn-success">
|
||||||
|
<i class="fa fa-check"></i> Save
|
||||||
|
</button>
|
||||||
|
<a href="{% url "admins" %}" class="btn-shadow mr-3 btn btn-danger">
|
||||||
|
<i class="fa fa-times"></i> Cancel
|
||||||
|
</a>
|
||||||
|
{% endbuttons %}
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
{% endblock %}
|
67
templates/backend/profiles/index.html
Normal file
67
templates/backend/profiles/index.html
Normal file
|
@ -0,0 +1,67 @@
|
||||||
|
{% extends "backend/base.html" %}
|
||||||
|
{% block content %}
|
||||||
|
<div class="app-page-title">
|
||||||
|
<div class="page-title-wrapper">
|
||||||
|
<div class="page-title-heading">
|
||||||
|
<div class="page-title-icon">
|
||||||
|
<i class="fa fa-users-cog">
|
||||||
|
</i>
|
||||||
|
</div>
|
||||||
|
<div>Administrator Users
|
||||||
|
<div class="page-title-subheading">Create, edit and delete users with backend access
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="page-title-actions">
|
||||||
|
<a href="{% url "dbsettings_create" %}" type="button" data-toggle="tooltip" title="New Administrator" data-placement="bottom" class="btn-shadow mr-3 btn btn-success">
|
||||||
|
<i class="fa fa-plus"></i> New Administrator
|
||||||
|
</a>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-12 col-lg-0">
|
||||||
|
<div class="mb-3 card">
|
||||||
|
<div class="card-header-tab card-header-tab-animation card-header">
|
||||||
|
<div class="card-header-title">
|
||||||
|
<i class="header-icon lnr-apartment icon-gradient bg-love-kiss"> </i>
|
||||||
|
Active Users
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="card-body">
|
||||||
|
<div class="tab-content">
|
||||||
|
<div class="tab-pane fade show active" id="tabs-eg-77">
|
||||||
|
<div class="card mb-3 widget-chart widget-chart2 text-left w-100">
|
||||||
|
<table class="mb-0 table table-hover">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>First Name</th>
|
||||||
|
<th>Last Name</th>
|
||||||
|
<th>Role</th>
|
||||||
|
<th>Email</th>
|
||||||
|
<th>Mobile</th>
|
||||||
|
<th>Options</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{% for admin in object_list %}
|
||||||
|
<tr>
|
||||||
|
<td>{{ admin.user.first_name }}</td>
|
||||||
|
<td>{{ admin.user.last_name }}</td>
|
||||||
|
<td>{{ admin.role }}</td>
|
||||||
|
<td>{{ admin.user.username }}</td>
|
||||||
|
<td>{{ admin.mobile }}</td>
|
||||||
|
<td><a href=""><i class="fas fa-edit" title="Edit Setting"></i></a> <a href=""><i style="color: darkred;" class="fas fa-trash-alt" title="Delete Setting"></i></a></td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endblock %}
|
57
templates/backend/profiles/update.html
Normal file
57
templates/backend/profiles/update.html
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
{% extends "backend/base.html" %}
|
||||||
|
{% load bootstrap4 %}
|
||||||
|
{% block content %}
|
||||||
|
<div class="app-page-title">
|
||||||
|
<div class="page-title-wrapper">
|
||||||
|
<div class="page-title-heading">
|
||||||
|
<div class="page-title-icon">
|
||||||
|
<i class="fa fa-users-cog">
|
||||||
|
</i>
|
||||||
|
</div>
|
||||||
|
<div>Administrator Users - Edit User
|
||||||
|
<div class="page-title-subheading">Edit adminstrator user properties
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="page-title-actions">
|
||||||
|
<button type="button" data-toggle="tooltip" title="New Setting" data-placement="bottom" class="btn-shadow mr-3 btn btn-success">
|
||||||
|
<i class="fa fa-plus"></i> New Administrator
|
||||||
|
</button>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-12 col-lg-0">
|
||||||
|
<div class="mb-3 card">
|
||||||
|
<div class="card-header-tab card-header-tab-animation card-header">
|
||||||
|
<div class="card-header-title">
|
||||||
|
<i class="header-icon lnr-apartment icon-gradient bg-love-kiss"> </i>
|
||||||
|
Editing {{ form.email.value }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="card-body">
|
||||||
|
<div class="tab-content">
|
||||||
|
<div class="tab-pane fade show active" id="tabs-eg-77">
|
||||||
|
<form method="POST">
|
||||||
|
{% csrf_token %}
|
||||||
|
{% bootstrap_form form %}
|
||||||
|
{% buttons %}
|
||||||
|
<button type="submit" class="btn-shadow mr-3 btn btn-success">
|
||||||
|
<i class="fa fa-check"></i> Save
|
||||||
|
</button>
|
||||||
|
<a href="{% url "dbsettings" %}" class="btn-shadow mr-3 btn btn-danger">
|
||||||
|
<i class="fa fa-times"></i> Cancel
|
||||||
|
</a>
|
||||||
|
{% endbuttons %}
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
{% endblock %}
|
Loading…
Reference in a new issue