Compare commits
	
		
			10 Commits
		
	
	
		
			main
			...
			feature/cs
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 0f69c44cc3 | |||
| ac26050a78 | |||
| c5dfb4f926 | |||
| 4c5a5fee8d | |||
| 17647bf4b7 | |||
| 4deeb3d773 | |||
| 5342e62bcb | |||
| 02512c1677 | |||
| ba6a40fbe5 | |||
| bce03d0500 | 
							
								
								
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1 @@
 | 
			
		||||
django_web_galleries/media/*
 | 
			
		||||
							
								
								
									
										5
									
								
								Pipfile
									
									
									
									
									
								
							
							
						
						
									
										5
									
								
								Pipfile
									
									
									
									
									
								
							@@ -5,8 +5,9 @@ name = "pypi"
 | 
			
		||||
 | 
			
		||||
[packages]
 | 
			
		||||
django = "*"
 | 
			
		||||
 | 
			
		||||
[dev-packages]
 | 
			
		||||
django-responsive-images = "*"
 | 
			
		||||
pillow = "*"
 | 
			
		||||
django-widget-tweaks = "*"
 | 
			
		||||
 | 
			
		||||
[requires]
 | 
			
		||||
python_version = "3.8"
 | 
			
		||||
 
 | 
			
		||||
@@ -37,6 +37,9 @@ INSTALLED_APPS = [
 | 
			
		||||
    'django.contrib.sessions',
 | 
			
		||||
    'django.contrib.messages',
 | 
			
		||||
    'django.contrib.staticfiles',
 | 
			
		||||
    'responsive_images',
 | 
			
		||||
    'widget_tweaks',
 | 
			
		||||
    'web_galleries',
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
MIDDLEWARE = [
 | 
			
		||||
@@ -115,9 +118,13 @@ USE_TZ = True
 | 
			
		||||
# Static files (CSS, JavaScript, Images)
 | 
			
		||||
# https://docs.djangoproject.com/en/4.1/howto/static-files/
 | 
			
		||||
 | 
			
		||||
STATIC_ROOT = BASE_DIR / 'static'
 | 
			
		||||
STATIC_URL = 'static/'
 | 
			
		||||
 | 
			
		||||
# Default primary key field type
 | 
			
		||||
# https://docs.djangoproject.com/en/4.1/ref/settings/#default-auto-field
 | 
			
		||||
 | 
			
		||||
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
 | 
			
		||||
 | 
			
		||||
MEDIA_ROOT = BASE_DIR / 'media'
 | 
			
		||||
MEDIA_URL = 'media/'
 | 
			
		||||
@@ -14,8 +14,9 @@ Including another URLconf
 | 
			
		||||
    2. Add a URL to urlpatterns:  path('blog/', include('blog.urls'))
 | 
			
		||||
"""
 | 
			
		||||
from django.contrib import admin
 | 
			
		||||
from django.urls import path
 | 
			
		||||
from django.urls import path, include
 | 
			
		||||
 | 
			
		||||
urlpatterns = [
 | 
			
		||||
    path('admin/', admin.site.urls),
 | 
			
		||||
    path('', include('web_galleries.urls'))
 | 
			
		||||
]
 | 
			
		||||
 
 | 
			
		||||
@@ -1,3 +1,11 @@
 | 
			
		||||
from django.contrib import admin
 | 
			
		||||
 | 
			
		||||
# Register your models here.
 | 
			
		||||
from .models import (
 | 
			
		||||
    Image,
 | 
			
		||||
    Visitor,
 | 
			
		||||
    Gallery
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
admin.site.register(Image)
 | 
			
		||||
admin.site.register(Visitor)
 | 
			
		||||
admin.site.register(Gallery)
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										9
									
								
								django_web_galleries/web_galleries/forms.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								django_web_galleries/web_galleries/forms.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,9 @@
 | 
			
		||||
from django import forms
 | 
			
		||||
from django.utils.translation import gettext as _
 | 
			
		||||
 | 
			
		||||
from .models import Image
 | 
			
		||||
 | 
			
		||||
class ImageUploadForm(forms.ModelForm):
 | 
			
		||||
    class Meta:
 | 
			
		||||
        model = Image
 | 
			
		||||
        fields = ['description', 'image_file', 'private']
 | 
			
		||||
@@ -0,0 +1,55 @@
 | 
			
		||||
# Generated by Django 4.1.4 on 2022-12-18 08:19
 | 
			
		||||
 | 
			
		||||
from django.db import migrations, models
 | 
			
		||||
import django.db.models.deletion
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Migration(migrations.Migration):
 | 
			
		||||
 | 
			
		||||
    initial = True
 | 
			
		||||
 | 
			
		||||
    dependencies = [
 | 
			
		||||
    ]
 | 
			
		||||
 | 
			
		||||
    operations = [
 | 
			
		||||
        migrations.CreateModel(
 | 
			
		||||
            name='Gallery',
 | 
			
		||||
            fields=[
 | 
			
		||||
                ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
 | 
			
		||||
                ('title', models.CharField(max_length=100, null=True, verbose_name='Optional title for this gallery')),
 | 
			
		||||
                ('private', models.BooleanField(blank=True, default=False, verbose_name='Wether the gallery is vsibile publicly or to certain users only')),
 | 
			
		||||
                ('access_code', models.CharField(max_length=32, null=True, verbose_name='Code to access private galleries')),
 | 
			
		||||
            ],
 | 
			
		||||
        ),
 | 
			
		||||
        migrations.CreateModel(
 | 
			
		||||
            name='Visitor',
 | 
			
		||||
            fields=[
 | 
			
		||||
                ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
 | 
			
		||||
                ('session_id', models.CharField(max_length=50, verbose_name='A cookie set by this application to identify a visitor by session')),
 | 
			
		||||
                ('name', models.CharField(default=None, max_length=50, null=True, unique=True, verbose_name='Human readable, self assigned name of the visitor')),
 | 
			
		||||
            ],
 | 
			
		||||
        ),
 | 
			
		||||
        migrations.CreateModel(
 | 
			
		||||
            name='Image',
 | 
			
		||||
            fields=[
 | 
			
		||||
                ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
 | 
			
		||||
                ('description', models.TextField(null=True, verbose_name='An optional description of the Image')),
 | 
			
		||||
                ('image_file', models.ImageField(upload_to='web_galleries/uploads/', verbose_name='File of the image')),
 | 
			
		||||
                ('private', models.BooleanField(blank=True, default=False, verbose_name='Wether this image is visible publicly or to certain users only')),
 | 
			
		||||
                ('access_code', models.CharField(max_length=32, null=True, verbose_name='Code to access private images')),
 | 
			
		||||
                ('uploaded_when', models.DateTimeField(auto_now_add=True, verbose_name='When this picture was uploaded')),
 | 
			
		||||
                ('galleries', models.ManyToManyField(related_name='images', to='web_galleries.gallery', verbose_name='What galleries this image is in')),
 | 
			
		||||
                ('uploaded_by', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='uploaded_images', to='web_galleries.visitor', verbose_name='Which visitor uploaded this picture')),
 | 
			
		||||
            ],
 | 
			
		||||
        ),
 | 
			
		||||
        migrations.AddField(
 | 
			
		||||
            model_name='gallery',
 | 
			
		||||
            name='created_by',
 | 
			
		||||
            field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='created_galleries', to='web_galleries.visitor', verbose_name='Visitor who created the gallery'),
 | 
			
		||||
        ),
 | 
			
		||||
        migrations.AddField(
 | 
			
		||||
            model_name='gallery',
 | 
			
		||||
            name='visitors',
 | 
			
		||||
            field=models.ManyToManyField(related_name='linked_galleries', to='web_galleries.visitor', verbose_name='Visitors that a part of this gallery'),
 | 
			
		||||
        ),
 | 
			
		||||
    ]
 | 
			
		||||
@@ -1,3 +1,107 @@
 | 
			
		||||
from django.db import models
 | 
			
		||||
from django.core.exceptions import ValidationError
 | 
			
		||||
from django.utils.translation import gettext as _
 | 
			
		||||
 | 
			
		||||
class Visitor(models.Model):
 | 
			
		||||
    """
 | 
			
		||||
    Stores information about a visitor of this application.
 | 
			
		||||
    No personal information is gathered, the name is optional and can be anything.
 | 
			
		||||
    The name has to be unique, tho.
 | 
			
		||||
    """
 | 
			
		||||
    session_id = models.CharField(
 | 
			
		||||
        _('A cookie set by this application to identify a visitor by session'),
 | 
			
		||||
        max_length=50
 | 
			
		||||
    )
 | 
			
		||||
    name = models.CharField(
 | 
			
		||||
        _('Human readable, self assigned name of the visitor'),
 | 
			
		||||
        null=True,
 | 
			
		||||
        default=None,
 | 
			
		||||
        max_length=50,
 | 
			
		||||
        unique=True
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Gallery(models.Model):
 | 
			
		||||
    """
 | 
			
		||||
    A gallery is a collection of multiple images.
 | 
			
		||||
    It must be 
 | 
			
		||||
    """
 | 
			
		||||
    title = models.CharField(
 | 
			
		||||
        _('Optional title for this gallery'),
 | 
			
		||||
        null=True,
 | 
			
		||||
        max_length=100
 | 
			
		||||
    )
 | 
			
		||||
    private = models.BooleanField(
 | 
			
		||||
        _('Wether the gallery is vsibile publicly or to certain users only'),
 | 
			
		||||
        default=False,
 | 
			
		||||
        blank=True
 | 
			
		||||
    )
 | 
			
		||||
    access_code = models.CharField(
 | 
			
		||||
        _('Code to access private galleries'),
 | 
			
		||||
        null=True,
 | 
			
		||||
        max_length=32
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
    created_by = models.ForeignKey(
 | 
			
		||||
        Visitor,
 | 
			
		||||
        verbose_name=_('Visitor who created the gallery'),
 | 
			
		||||
        related_name='created_galleries',
 | 
			
		||||
        on_delete=models.CASCADE
 | 
			
		||||
    )
 | 
			
		||||
        
 | 
			
		||||
    visitors = models.ManyToManyField(
 | 
			
		||||
        Visitor,
 | 
			
		||||
        verbose_name=_('Visitors that a part of this gallery'),
 | 
			
		||||
        related_name='linked_galleries'
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
    def clean(self):
 | 
			
		||||
        if self.private and access_code is None:
 | 
			
		||||
            raise ValidationErrorr('Private gallery needs an access code')
 | 
			
		||||
        if len(self.visitors.all()) > 10:
 | 
			
		||||
            raise ValidationError('Gallery can not have more than 10 visitors assigned')
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Image(models.Model):
 | 
			
		||||
    """
 | 
			
		||||
    An image contains the path to the image file and several information
 | 
			
		||||
    like description, uploader and affiliation to galleries.
 | 
			
		||||
    """
 | 
			
		||||
    description = models.TextField(
 | 
			
		||||
        _('An optional description of the Image'),
 | 
			
		||||
        null=True
 | 
			
		||||
    )
 | 
			
		||||
    image_file = models.ImageField(
 | 
			
		||||
        _('File of the image'),
 | 
			
		||||
        upload_to='web_galleries/uploads/'
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
    private = models.BooleanField(
 | 
			
		||||
        _('Wether this image is visible publicly or to certain users only'),
 | 
			
		||||
        default=False,
 | 
			
		||||
        blank=True
 | 
			
		||||
    )
 | 
			
		||||
    access_code = models.CharField(
 | 
			
		||||
        _('Code to access private images'),
 | 
			
		||||
        null=True,
 | 
			
		||||
        max_length=32
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
    uploaded_by = models.ForeignKey(
 | 
			
		||||
        Visitor,
 | 
			
		||||
        verbose_name=_('Which visitor uploaded this picture'),
 | 
			
		||||
        null=True,
 | 
			
		||||
        related_name='uploaded_images',
 | 
			
		||||
        on_delete=models.SET_NULL
 | 
			
		||||
    )
 | 
			
		||||
    uploaded_when = models.DateTimeField(
 | 
			
		||||
        _('When this picture was uploaded'),
 | 
			
		||||
        auto_now_add=True
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
    galleries = models.ManyToManyField(
 | 
			
		||||
        Gallery,
 | 
			
		||||
        verbose_name=_('What galleries this image is in'),
 | 
			
		||||
        related_name='images'
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
# Create your models here.
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										74
									
								
								django_web_galleries/web_galleries/static/web-galleries.css
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										74
									
								
								django_web_galleries/web_galleries/static/web-galleries.css
									
									
									
									
									
										Normal 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;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										49
									
								
								django_web_galleries/web_galleries/templates/global.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										49
									
								
								django_web_galleries/web_galleries/templates/global.html
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,49 @@
 | 
			
		||||
{% load static %}
 | 
			
		||||
 | 
			
		||||
<!DOCTYPE html>
 | 
			
		||||
<html lang="en">
 | 
			
		||||
<head>
 | 
			
		||||
    <meta charset="UTF-8">
 | 
			
		||||
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
 | 
			
		||||
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
 | 
			
		||||
    <title>Web Gallery</title>
 | 
			
		||||
    <link rel="stylesheet" href="{% static 'web-galleries.css' %}">
 | 
			
		||||
</head>
 | 
			
		||||
<body>
 | 
			
		||||
    <div class="RV-Page">
 | 
			
		||||
        <header class="RV-Header">
 | 
			
		||||
            <nav class="RV-Navigation">
 | 
			
		||||
                <ul class="RV-Navigation__list">
 | 
			
		||||
                    <li class="RV-Navigation__item">
 | 
			
		||||
                        <a href="{% url 'home' %}" class="RV-Navigation__link">
 | 
			
		||||
                            Home
 | 
			
		||||
                        </a>
 | 
			
		||||
                    </li>
 | 
			
		||||
                    <li class="RV-Navigation__item">
 | 
			
		||||
                        <a href="{% url 'upload_image' %}" class="RV-Navigation__link">
 | 
			
		||||
                            Upload image
 | 
			
		||||
                        </a>
 | 
			
		||||
                    </li>
 | 
			
		||||
                    <li class="RV-Navigation__item">
 | 
			
		||||
                        <a href="#" class="RV-Navigation__link">
 | 
			
		||||
                            My galleries
 | 
			
		||||
                        </a>
 | 
			
		||||
                    </li>
 | 
			
		||||
                    <li class="RV-Navigation__item">
 | 
			
		||||
                        <a href="#" class="RV-Navigation__link">
 | 
			
		||||
                            Create gallery
 | 
			
		||||
                        </a>
 | 
			
		||||
                    </li>
 | 
			
		||||
                </ul>
 | 
			
		||||
            </nav>
 | 
			
		||||
        </header>
 | 
			
		||||
        <main class="RV-Content">
 | 
			
		||||
            {% block content %}
 | 
			
		||||
            {% endblock content %}
 | 
			
		||||
        </main>
 | 
			
		||||
        <footer class="RV-Footer">
 | 
			
		||||
            
 | 
			
		||||
        </footer>
 | 
			
		||||
    </div>
 | 
			
		||||
</body>
 | 
			
		||||
</html>
 | 
			
		||||
@@ -0,0 +1,15 @@
 | 
			
		||||
{% extends '../global.html' %}
 | 
			
		||||
 | 
			
		||||
{% load responsive_images %}
 | 
			
		||||
 | 
			
		||||
{% block content %}
 | 
			
		||||
    <sectoin class="RV-Images">
 | 
			
		||||
        <li class="RV-Images__list">
 | 
			
		||||
            {% for image in images %}
 | 
			
		||||
                <a href="#" class="RV-Image__link RV-Image__link--detail">
 | 
			
		||||
                    <img class="RV-Image__source" src="{% src image.image_file 200x200 %}">
 | 
			
		||||
                </a>
 | 
			
		||||
            {% endfor %}
 | 
			
		||||
        </li>
 | 
			
		||||
    </sectoin>
 | 
			
		||||
{% endblock content %}
 | 
			
		||||
@@ -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>
 | 
			
		||||
@@ -0,0 +1,17 @@
 | 
			
		||||
{% extends '../global.html' %}
 | 
			
		||||
 | 
			
		||||
{% block content %}
 | 
			
		||||
    <form method="POST" enctype="multipart/form-data">
 | 
			
		||||
        {% csrf_token %}
 | 
			
		||||
        <div class="RV-Fieldset">
 | 
			
		||||
            {% 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>
 | 
			
		||||
{% endblock content %}
 | 
			
		||||
							
								
								
									
										19
									
								
								django_web_galleries/web_galleries/urls.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								django_web_galleries/web_galleries/urls.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,19 @@
 | 
			
		||||
from django.urls import path
 | 
			
		||||
from django.conf import settings
 | 
			
		||||
from django.conf.urls.static import static
 | 
			
		||||
 | 
			
		||||
from .views import (
 | 
			
		||||
    ImageUploadView,
 | 
			
		||||
    PublicImageListView
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
urlpatterns = [
 | 
			
		||||
    path('', PublicImageListView.as_view(), name='home'),
 | 
			
		||||
    path('upload/', ImageUploadView.as_view(), name='upload_image')
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
if settings.DEBUG:
 | 
			
		||||
    urlpatterns += static(
 | 
			
		||||
        settings.MEDIA_URL,
 | 
			
		||||
        document_root=settings.MEDIA_ROOT
 | 
			
		||||
    )
 | 
			
		||||
@@ -1,3 +1,55 @@
 | 
			
		||||
from django.shortcuts import render
 | 
			
		||||
import secrets
 | 
			
		||||
 | 
			
		||||
# Create your views here.
 | 
			
		||||
from django.views import View
 | 
			
		||||
from django.views.generic.list import ListView
 | 
			
		||||
from django.shortcuts import render, redirect
 | 
			
		||||
from django.urls import reverse
 | 
			
		||||
 | 
			
		||||
from .forms import ImageUploadForm
 | 
			
		||||
from .models import Image
 | 
			
		||||
 | 
			
		||||
class ImageUploadView(View):
 | 
			
		||||
    def get(self, request):
 | 
			
		||||
        form = ImageUploadForm()
 | 
			
		||||
        return render(
 | 
			
		||||
            request,
 | 
			
		||||
            'upload_image/upload.html',
 | 
			
		||||
            {
 | 
			
		||||
                'form': form
 | 
			
		||||
            }
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
    def post(self, request):
 | 
			
		||||
        form = ImageUploadForm(
 | 
			
		||||
            request.POST,
 | 
			
		||||
            request.FILES
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
        if form.is_valid():
 | 
			
		||||
            image = form.save(commit=False)
 | 
			
		||||
 | 
			
		||||
            if image.private:
 | 
			
		||||
                image.access_code = secrets.token_hex(32)
 | 
			
		||||
 | 
			
		||||
            image.save()
 | 
			
		||||
            return redirect(
 | 
			
		||||
                reverse('home')
 | 
			
		||||
            )
 | 
			
		||||
        else:
 | 
			
		||||
            form = ImageUploadForm()
 | 
			
		||||
            return render(
 | 
			
		||||
                request,
 | 
			
		||||
                'upload_image/upload.html',
 | 
			
		||||
                {
 | 
			
		||||
                    'form': form
 | 
			
		||||
                }
 | 
			
		||||
            )
 | 
			
		||||
 | 
			
		||||
class PublicImageListView(ListView):
 | 
			
		||||
    model = Image
 | 
			
		||||
    paginate_by = 20
 | 
			
		||||
    context_object_name = 'images'
 | 
			
		||||
    template_name = 'list_images/image_list.html'
 | 
			
		||||
 | 
			
		||||
    def get_queryset(self):
 | 
			
		||||
        return Image.objects.all().filter(private=False)
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user