Add login and sign up logic to the app
This commit is contained in:
parent
b12baaf09b
commit
a4118e2357
@ -1,8 +1,12 @@
|
|||||||
from django.urls import path
|
from django.urls import path, include
|
||||||
from . import views
|
from . import views
|
||||||
from django.conf.urls.static import static
|
from django.conf.urls.static import static
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
|
from django.contrib.auth import urls
|
||||||
|
|
||||||
urlpatterns = [path("detect/", views.view, name="detect")] + static(
|
urlpatterns = [
|
||||||
settings.MEDIA_URL, document_root=settings.MEDIA_ROOT
|
path("detect/", views.DetectView.as_view(), name="detect"),
|
||||||
)
|
path("login/", views.LoginView.as_view(), name="login"),
|
||||||
|
path("logout/", views.logout_view, name="logout"),
|
||||||
|
path("register/", views.SignupView.as_view(), name="signup"),
|
||||||
|
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
|
||||||
|
@ -1,37 +1,85 @@
|
|||||||
from django.shortcuts import render
|
from django.shortcuts import render, redirect
|
||||||
|
from django.views import View
|
||||||
from .forms import DetectForm
|
from .forms import DetectForm
|
||||||
from .models import DetectImage
|
|
||||||
from django.core.files.uploadedfile import SimpleUploadedFile
|
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from ultralytics import YOLO
|
from ultralytics import YOLO
|
||||||
|
from django.contrib.auth.forms import AuthenticationForm, UserCreationForm
|
||||||
|
from django.contrib.auth import authenticate, login, logout
|
||||||
|
|
||||||
# Create your views here.
|
# Create your views here.
|
||||||
MODEL = YOLO("best.pt")
|
MODEL = YOLO("best.pt")
|
||||||
|
|
||||||
|
|
||||||
def view(request):
|
class DetectView(View):
|
||||||
if request.method == "GET":
|
form_class = DetectForm
|
||||||
form = DetectForm()
|
template_name = "upload.html"
|
||||||
return render(request, "upload.html", {"form": form})
|
|
||||||
form = DetectForm(request.POST, request.FILES)
|
def get(self, request, *args, **kwargs):
|
||||||
if form.is_valid():
|
form = self.form_class()
|
||||||
image = form.save()
|
|
||||||
MODEL.predict(
|
|
||||||
image.image.path,
|
|
||||||
save=True,
|
|
||||||
project=settings.MEDIA_ROOT,
|
|
||||||
name=f"{image.image.name}_predicted",
|
|
||||||
imgsz=[640, 640],
|
|
||||||
)
|
|
||||||
print(f"{settings.BASE_DIR}/predicted2/{image.image.name}")
|
|
||||||
saved = form.is_valid()
|
|
||||||
return render(
|
|
||||||
request,
|
|
||||||
"upload.html",
|
|
||||||
{
|
|
||||||
"img_saved": saved,
|
|
||||||
"img_path": f"{image.image.name}_predicted/{image.image.name.split('/')[-1]}",
|
|
||||||
},
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
return render(request, "upload.html", {"form": form})
|
return render(request, "upload.html", {"form": form})
|
||||||
|
|
||||||
|
def post(self, request, *args, **kwargs):
|
||||||
|
form = self.form_class(request.POST, request.FILES)
|
||||||
|
if form.is_valid():
|
||||||
|
image = form.save()
|
||||||
|
MODEL.predict(
|
||||||
|
image.image.path,
|
||||||
|
save=True,
|
||||||
|
project=settings.MEDIA_ROOT,
|
||||||
|
name=f"{image.image.name}_predicted",
|
||||||
|
imgsz=[640, 640],
|
||||||
|
)
|
||||||
|
saved = form.is_valid()
|
||||||
|
return render(
|
||||||
|
request,
|
||||||
|
"upload.html",
|
||||||
|
{
|
||||||
|
"img_saved": saved,
|
||||||
|
"img_path": f"{image.image.name}_predicted/{image.image.name.split('/')[-1]}",
|
||||||
|
},
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
return render(request, "upload.html", {"form": form})
|
||||||
|
|
||||||
|
|
||||||
|
class LoginView(View):
|
||||||
|
form_class = AuthenticationForm
|
||||||
|
template_name = "login_signup.html"
|
||||||
|
|
||||||
|
def get(self, request, *args, **kwargs):
|
||||||
|
form = self.form_class()
|
||||||
|
return render(request, self.template_name, {"form": form})
|
||||||
|
|
||||||
|
def post(self, request, *args, **kwargs):
|
||||||
|
form = self.form_class(data=request.POST)
|
||||||
|
if form.is_valid():
|
||||||
|
user = authenticate(
|
||||||
|
username=form.cleaned_data["username"],
|
||||||
|
password=form.cleaned_data["password"],
|
||||||
|
)
|
||||||
|
if user is not None:
|
||||||
|
login(request, user)
|
||||||
|
return redirect("detect")
|
||||||
|
return render(request, self.template_name, {"form": form})
|
||||||
|
|
||||||
|
|
||||||
|
class SignupView(View):
|
||||||
|
form_class = UserCreationForm
|
||||||
|
template_name = "login_signup.html"
|
||||||
|
|
||||||
|
def get(self, request, *args, **kwargs):
|
||||||
|
form = self.form_class()
|
||||||
|
return render(request, self.template_name, {"form": form, "signup": True})
|
||||||
|
|
||||||
|
def post(self, request, *args, **kwargs):
|
||||||
|
form = self.form_class(data=request.POST)
|
||||||
|
if form.is_valid():
|
||||||
|
user = form.save()
|
||||||
|
login(request, user)
|
||||||
|
return redirect("detect")
|
||||||
|
return render(request, self.template_name, {"form": form, "signup": True})
|
||||||
|
|
||||||
|
|
||||||
|
def logout_view(request):
|
||||||
|
logout(request)
|
||||||
|
return redirect("detect")
|
||||||
|
@ -56,7 +56,7 @@ ROOT_URLCONF = "PlanktonDetector.urls"
|
|||||||
TEMPLATES = [
|
TEMPLATES = [
|
||||||
{
|
{
|
||||||
"BACKEND": "django.template.backends.django.DjangoTemplates",
|
"BACKEND": "django.template.backends.django.DjangoTemplates",
|
||||||
"DIRS": [os.path.join(BASE_DIR, 'templates')],
|
"DIRS": [os.path.join(BASE_DIR, "templates")],
|
||||||
"APP_DIRS": True,
|
"APP_DIRS": True,
|
||||||
"OPTIONS": {
|
"OPTIONS": {
|
||||||
"context_processors": [
|
"context_processors": [
|
||||||
@ -119,14 +119,16 @@ USE_TZ = True
|
|||||||
|
|
||||||
STATIC_URL = "static/"
|
STATIC_URL = "static/"
|
||||||
|
|
||||||
STATIC_ROOT = ''
|
STATIC_ROOT = ""
|
||||||
|
|
||||||
STATICFILES_DIRS = ('static',)
|
STATICFILES_DIRS = ("static",)
|
||||||
|
|
||||||
MEDIA_ROOT = BASE_DIR / "uploaded_media"
|
MEDIA_ROOT = BASE_DIR / "uploaded_media"
|
||||||
|
|
||||||
MEDIA_URL = "media/"
|
MEDIA_URL = "media/"
|
||||||
|
|
||||||
|
LOGOUT_REDIRECT_URL = "detect/"
|
||||||
|
|
||||||
# Default primary key field type
|
# Default primary key field type
|
||||||
# https://docs.djangoproject.com/en/4.2/ref/settings/#default-auto-field
|
# https://docs.djangoproject.com/en/4.2/ref/settings/#default-auto-field
|
||||||
|
|
||||||
|
Binary file not shown.
40
PlanktonDetector/static/DetectionApp/css/base.css
Normal file
40
PlanktonDetector/static/DetectionApp/css/base.css
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
body, html{
|
||||||
|
height:100%;
|
||||||
|
margin: 0px 0px 0px 0px;
|
||||||
|
display:flex;
|
||||||
|
justify-content: center;
|
||||||
|
flex-direction: column;
|
||||||
|
font-family:'Inter', sans-serif;
|
||||||
|
}
|
||||||
|
|
||||||
|
.top-menu a{
|
||||||
|
text-decoration: none;
|
||||||
|
margin-right: 2rem;
|
||||||
|
color:black;
|
||||||
|
}
|
||||||
|
|
||||||
|
.top-menu{
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
height: 5%;
|
||||||
|
justify-content:flex-end;
|
||||||
|
align-items: center;
|
||||||
|
background-color:lightgray;
|
||||||
|
margin-bottom:5px;
|
||||||
|
border: grey solid;
|
||||||
|
border-width: 0px 2px 2px 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.footer{
|
||||||
|
display:flex;
|
||||||
|
flex-direction: row;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
margin-top: 5px;
|
||||||
|
background-color: lightgray;
|
||||||
|
border: grey solid;
|
||||||
|
border-width: 2px 2px 0px 2px;
|
||||||
|
justify-content: space-evenly;
|
||||||
|
align-items: center;
|
||||||
|
}
|
33
PlanktonDetector/static/DetectionApp/css/login_signup.css
Normal file
33
PlanktonDetector/static/DetectionApp/css/login_signup.css
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
.form_div{
|
||||||
|
height: 100%;
|
||||||
|
width: 100%;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form_div input,label, p{
|
||||||
|
font-size: 1.2rem;
|
||||||
|
margin-bottom: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form{
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-evenly;
|
||||||
|
border: grey solid;
|
||||||
|
border-width: 4px;
|
||||||
|
border-radius: 10%;
|
||||||
|
padding: 5%;
|
||||||
|
background-color: lightgray;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form span{
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
#submit{
|
||||||
|
background-color: chartreuse;
|
||||||
|
}
|
@ -1,32 +1,34 @@
|
|||||||
html, body, form{
|
|
||||||
|
form{
|
||||||
height:100%;
|
height:100%;
|
||||||
width: 100%;
|
width:100%;
|
||||||
display:flex;
|
display:flex;
|
||||||
flex-direction: row;
|
flex-direction:row;
|
||||||
font-family:'Inter', sans-serif;
|
margin:auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
.side_menu{
|
.side_menu{
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: flex-start;
|
justify-content: center;
|
||||||
align-items:center;
|
align-items:center;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
width: 25%;
|
width: 25%;
|
||||||
background-color: lightgray;
|
background-color: lightgray;
|
||||||
|
border: grey solid;
|
||||||
|
border-width: 2px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#description{
|
#description{
|
||||||
font-size: 40px;
|
font-size: 40px;
|
||||||
margin-left: 10px;
|
text-align: center;
|
||||||
margin-right: 10px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#submit{
|
#submit{
|
||||||
margin-bottom: 40px;
|
margin-bottom: 40px;
|
||||||
background-color: chartreuse;
|
background-color: chartreuse;
|
||||||
margin-top: auto;
|
margin-top: auto;
|
||||||
justify-self: flex-end;
|
|
||||||
height: 50px;
|
height: 50px;
|
||||||
width: 80%;
|
width: 80%;
|
||||||
border-radius: 25px;
|
border-radius: 25px;
|
||||||
@ -44,7 +46,6 @@ html, body, form{
|
|||||||
|
|
||||||
|
|
||||||
.upload_button{
|
.upload_button{
|
||||||
justify-self: right;
|
|
||||||
display:flex;
|
display:flex;
|
||||||
justify-content: flex-start;
|
justify-content: flex-start;
|
||||||
align-items: flex-start;
|
align-items: flex-start;
|
30
PlanktonDetector/templates/base.html
Normal file
30
PlanktonDetector/templates/base.html
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
{% load static %}
|
||||||
|
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||||
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||||
|
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300&display=swap" rel="stylesheet">
|
||||||
|
<link rel="stylesheet" href="{% static 'DetectionApp/css/base.css' %}">
|
||||||
|
{%block extracss%}{%endblock extracss%}
|
||||||
|
<title>Plankton Detector</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="top-menu">
|
||||||
|
<a href="#">Placeholder</a>
|
||||||
|
<a href="{% url 'detect' %}">Predict</a>
|
||||||
|
{% if user.is_authenticated %}
|
||||||
|
<a href="{% url 'logout' %}">Logout {{user}}</a>
|
||||||
|
{%else%}
|
||||||
|
<a href="{% url 'login' %}">Login</a>
|
||||||
|
{%endif%}
|
||||||
|
</div>
|
||||||
|
{%block content%}{%endblock content%}
|
||||||
|
<div class="footer">
|
||||||
|
<p>Footer</p>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
25
PlanktonDetector/templates/login_signup.html
Normal file
25
PlanktonDetector/templates/login_signup.html
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
{% extends 'base.html' %}
|
||||||
|
{%load static%}
|
||||||
|
{%block extracss%}
|
||||||
|
<link rel="stylesheet" href="{% static 'DetectionApp/css/login_signup.css' %}">
|
||||||
|
{%endblock extracss%}
|
||||||
|
{%block content%}
|
||||||
|
<div class="form_div">
|
||||||
|
{%if signup is not None%}
|
||||||
|
<p class="top_label">Register</p>
|
||||||
|
{% else%}
|
||||||
|
<p class="top_label">Login</p>
|
||||||
|
{%endif%}
|
||||||
|
<form class="form" method="post">
|
||||||
|
{%csrf_token%}
|
||||||
|
{{form}}
|
||||||
|
{% if signup is None%}
|
||||||
|
<input type="submit" id="submit" value="Log in">
|
||||||
|
</form>
|
||||||
|
<p class="signup_label">Don't have an account? <a href="{%url 'signup'%}">Sign Up</a></p>
|
||||||
|
{%else%}
|
||||||
|
<input type="submit" id="submit" value="Sign Up">
|
||||||
|
</form>
|
||||||
|
{%endif%}
|
||||||
|
</div>
|
||||||
|
{%endblock content%}
|
@ -1,16 +1,9 @@
|
|||||||
<!DOCTYPE html>
|
{% extends 'base.html' %}
|
||||||
<html lang="en">
|
{%load static%}
|
||||||
{% load static %}
|
{%block extracss%}
|
||||||
<head>
|
<link rel="stylesheet" href="{%static 'DetectionApp/css/upload.css' %}">
|
||||||
<meta charset="UTF-8">
|
{%endblock extracss%}
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
{%block content%}
|
||||||
<title>Plankton Detector</title>
|
|
||||||
<link rel="stylesheet" href="{% static 'DetectionApp/css/styles.css' %}">
|
|
||||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
|
||||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
|
||||||
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300&display=swap" rel="stylesheet">
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<form method="POST" enctype="multipart/form-data">
|
<form method="POST" enctype="multipart/form-data">
|
||||||
{% csrf_token %}
|
{% csrf_token %}
|
||||||
<div class="side_menu">
|
<div class="side_menu">
|
||||||
@ -50,5 +43,4 @@
|
|||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
</form>
|
</form>
|
||||||
</body>
|
{%endblock content%}
|
||||||
</html>
|
|
Loading…
Reference in New Issue
Block a user