Compare commits

...

4 Commits

Author SHA1 Message Date
reverend 1df19b8a74 Assigning Visitors to Sessions and Images 2022-12-25 12:20:38 +01:00
reverend 8c06ce09fa Representation of an image in the admin view 2022-12-25 12:20:13 +01:00
reverend b0d9c46eb2 #2 Handling image upload 2022-12-25 12:19:54 +01:00
reverend 0f69c44cc3 #3 CSS and HTML 2022-12-25 12:18:15 +01:00
13 changed files with 172 additions and 20 deletions

3
.gitignore vendored
View File

@ -1 +1,2 @@
django_web_galleries/media/* django_web_galleries/media/*
django_web_galleries/static/*

View File

@ -7,8 +7,7 @@ name = "pypi"
django = "*" django = "*"
django-responsive-images = "*" django-responsive-images = "*"
pillow = "*" pillow = "*"
django-widget-tweaks = "*"
[dev-packages]
[requires] [requires]
python_version = "3.8" python_version = "3.8"

View File

@ -38,6 +38,7 @@ INSTALLED_APPS = [
'django.contrib.messages', 'django.contrib.messages',
'django.contrib.staticfiles', 'django.contrib.staticfiles',
'responsive_images', 'responsive_images',
'widget_tweaks',
'web_galleries', 'web_galleries',
] ]

View File

@ -16,7 +16,20 @@ Including another URLconf
from django.contrib import admin from django.contrib import admin
from django.urls import path, include from django.urls import path, include
from django.conf import settings
from django.conf.urls.static import static
urlpatterns = [ urlpatterns = [
path('admin/', admin.site.urls), path('admin/', admin.site.urls),
path('', include('web_galleries.urls')) path('', include('web_galleries.urls'))
] ]
if settings.DEBUG:
urlpatterns += static(
settings.MEDIA_URL,
document_root=settings.MEDIA_ROOT
)
urlpatterns += static(
settings.STATIC_URL,
document_root=settings.STATIC_ROOT
)

View File

@ -6,4 +6,7 @@ from .models import Image
class ImageUploadForm(forms.ModelForm): class ImageUploadForm(forms.ModelForm):
class Meta: class Meta:
model = Image model = Image
fields = ['description', 'image_file', 'private'] fields = ['description', 'image_file', 'private', 'title']
labels = {
'private': 'Make this image private'
}

View File

@ -1,7 +1,12 @@
import uuid
from django.db import models from django.db import models
from django.core.exceptions import ValidationError from django.core.exceptions import ValidationError
from django.utils.translation import gettext as _ from django.utils.translation import gettext as _
def get_uuid():
return str(uuid.uuid4())
class Visitor(models.Model): class Visitor(models.Model):
""" """
Stores information about a visitor of this application. Stores information about a visitor of this application.
@ -10,7 +15,8 @@ class Visitor(models.Model):
""" """
session_id = models.CharField( session_id = models.CharField(
_('A cookie set by this application to identify a visitor by session'), _('A cookie set by this application to identify a visitor by session'),
max_length=50 max_length=50,
default=get_uuid
) )
name = models.CharField( name = models.CharField(
_('Human readable, self assigned name of the visitor'), _('Human readable, self assigned name of the visitor'),
@ -67,6 +73,13 @@ class Image(models.Model):
An image contains the path to the image file and several information An image contains the path to the image file and several information
like description, uploader and affiliation to galleries. like description, uploader and affiliation to galleries.
""" """
title = models.CharField(
_('Title of the image'),
max_length=100,
null=True,
blank=True
)
description = models.TextField( description = models.TextField(
_('An optional description of the Image'), _('An optional description of the Image'),
null=True null=True
@ -105,3 +118,11 @@ class Image(models.Model):
related_name='images' related_name='images'
) )
def __str__(self):
if self.title:
return self.title
elif self.description:
return self.description[:100]
else:
return super.__str__()

View File

@ -0,0 +1,74 @@
.RV-Header {
height: 80px;
margin-bottom: 70px;
display: flex;
flex-direction: row;
align-items: center;
justify-content: flex-start;
border-bottom: 1px solid gray;
}
.RV-Navigation__list {
display: flex;
flex-direction: row;
list-style-type: none;
gap: 1em;
font-size: 22px;
}
.RV-Navigation__link {
text-decoration: none;
display: inline-block;
transition: transform 300ms ease-in-out;
}
.RV-Navigation__link:hover {
transform: scale(1.2);
}
.RV-Images__list {
list-style-type: none;
display: grid;
gap: 22px;
grid-template-columns: repeat(auto-fit, 200px);
}
.RV-Image__link {
transition: transform 300ms ease-in-out;
}
.RV-Image__link:hover {
transform: scale(1.1);
}
.RV-Fieldset {
margin: 50px 200px;
display: flex;
flex-direction: column;
gap: 30px;
}
.RV-Input {
display: flex;
flex-direction: column;
align-items: flex-start;
}
.RV-Input--compact {
flex-direction: row;
}
.RV-Input.RV-Input--reverse {
flex-direction: column-reverse;
align-items: flex-end;
}
.RV-Input--compact.RV-Input--reverse {
flex-direction: row-reverse;
justify-content: flex-end;
}

View File

@ -1,3 +1,5 @@
{% load static %}
<!DOCTYPE html> <!DOCTYPE html>
<html lang="en"> <html lang="en">
<head> <head>
@ -5,10 +7,11 @@
<meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Web Gallery</title> <title>Web Gallery</title>
<link rel="stylesheet" href="{% static 'web-galleries.css' %}">
</head> </head>
<body> <body>
<div class="RV-Page"> <div class="RV-Page">
<head class="RV-Head"> <header class="RV-Header">
<nav class="RV-Navigation"> <nav class="RV-Navigation">
<ul class="RV-Navigation__list"> <ul class="RV-Navigation__list">
<li class="RV-Navigation__item"> <li class="RV-Navigation__item">
@ -33,7 +36,7 @@
</li> </li>
</ul> </ul>
</nav> </nav>
</head> </header>
<main class="RV-Content"> <main class="RV-Content">
{% block content %} {% block content %}
{% endblock content %} {% endblock content %}

View File

@ -6,7 +6,9 @@
<sectoin class="RV-Images"> <sectoin class="RV-Images">
<li class="RV-Images__list"> <li class="RV-Images__list">
{% for image in images %} {% for image in images %}
<img src="{% src image.image_file 200x200 %}"> <a href="#" class="RV-Image__link RV-Image__link--detail">
<img class="RV-Image__source" src="{% src image.image_file 200x200 %}">
</a>
{% endfor %} {% endfor %}
</li> </li>
</sectoin> </sectoin>

View File

@ -0,0 +1,16 @@
{% load widget_tweaks %}
<div class="RV-Input {% if classes%}{{classes}}{% endif %} {% if field.errors %} RV-Input--error {% endif %}">
<label for="{{field.id_for_label}}" class="RV-Input__Label">{{field.label}}</label>
{% render_field field class+='RV-Input__Field' %}
<span class="RV-Input__Message">
{% if field.errors %}
{% for error in field.errors%}
{{error}}
{% endfor %}
{% elif field.help_text%}
{{ field.help_text }}
{% endif %}
</span>
</div>

View File

@ -3,7 +3,15 @@
{% block content %} {% block content %}
<form method="POST" enctype="multipart/form-data"> <form method="POST" enctype="multipart/form-data">
{% csrf_token %} {% csrf_token %}
{{ form }} <div class="RV-Fieldset">
<button type="submit">Upload</button> {% include 'partials/form_input.html' with field=form.title %}
{% include 'partials/form_input.html' with field=form.image_file %}
{% include 'partials/form_input.html' with field=form.description %}
{% include 'partials/form_input.html' with field=form.private classes='RV-Input--compact RV-Input--reverse' %}
</div>
<div class="RV-Fieldset">
<button type="submit">Upload</button>
</div>
</form> </form>
{% endblock content %} {% endblock content %}

View File

@ -1,6 +1,4 @@
from django.urls import path from django.urls import path
from django.conf import settings
from django.conf.urls.static import static
from .views import ( from .views import (
ImageUploadView, ImageUploadView,
@ -11,9 +9,3 @@ urlpatterns = [
path('', PublicImageListView.as_view(), name='home'), path('', PublicImageListView.as_view(), name='home'),
path('upload/', ImageUploadView.as_view(), name='upload_image') path('upload/', ImageUploadView.as_view(), name='upload_image')
] ]
if settings.DEBUG:
urlpatterns += static(
settings.MEDIA_URL,
document_root=settings.MEDIA_ROOT
)

View File

@ -6,9 +6,26 @@ from django.shortcuts import render, redirect
from django.urls import reverse from django.urls import reverse
from .forms import ImageUploadForm from .forms import ImageUploadForm
from .models import Image from .models import (
Image,
Visitor
)
class ImageUploadView(View): class VisitorSessionMixin(View):
def get_visitor(self):
if self.request.session:
if 'visitor_session' in self.request.session:
if Visitor.objects.get(session_id=self.request.session['visitor_session']).exists():
return Visitor.objects.get(session_id=self.request.session['visitor_session'])
else:
visitor = Visitor.objects.create()
self.request.session['visitor_session'] = visitor.session_id
return visitor
else:
return None
class ImageUploadView(VisitorSessionMixin, View):
def get(self, request): def get(self, request):
form = ImageUploadForm() form = ImageUploadForm()
return render( return render(
@ -31,6 +48,8 @@ class ImageUploadView(View):
if image.private: if image.private:
image.access_code = secrets.token_hex(32) image.access_code = secrets.token_hex(32)
image.uploaded_by = self.get_visitor()
print(image.uploaded_by)
image.save() image.save()
return redirect( return redirect(
reverse('home') reverse('home')