Limit upload file sizes

This commit is contained in:
Guillaume Bertholon 2020-12-30 00:31:58 +01:00
parent ee364e2561
commit 0ad6c7543e
4 changed files with 54 additions and 11 deletions

View file

@ -102,6 +102,8 @@ MARKDOWNX_MARKDOWN_EXTENSION_CONFIGS = {
} }
} }
MARKDOWNX_UPLOAD_MAX_SIZE = 1024 * 1024 # Only 1 MiB for markdown uploads
# Update the search database on save # Update the search database on save
HAYSTACK_SIGNAL_PROCESSOR = "haystack.signals.RealtimeSignalProcessor" HAYSTACK_SIGNAL_PROCESSOR = "haystack.signals.RealtimeSignalProcessor"

View file

@ -1,9 +1,10 @@
# Generated by Django 3.1.2 on 2020-12-27 17:01 # Generated by Django 3.1.2 on 2020-12-29 23:21
import autoslug.fields import autoslug.fields
from django.conf import settings from django.conf import settings
from django.db import migrations, models from django.db import migrations, models
import django.db.models.deletion import django.db.models.deletion
import website.validators
class Migration(migrations.Migration): class Migration(migrations.Migration):
@ -19,7 +20,7 @@ class Migration(migrations.Migration):
name='Category', name='Category',
fields=[ fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=256, verbose_name='nom')), ('name', models.CharField(max_length=256, unique=True, verbose_name='nom')),
('slug', autoslug.fields.AutoSlugField(editable=False, populate_from='name', unique=True)), ('slug', autoslug.fields.AutoSlugField(editable=False, populate_from='name', unique=True)),
], ],
options={ options={
@ -31,7 +32,7 @@ class Migration(migrations.Migration):
name='Game', name='Game',
fields=[ fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('title', models.CharField(max_length=256, verbose_name='titre')), ('title', models.CharField(max_length=256, unique=True, verbose_name='titre du jeu')),
('slug', autoslug.fields.AutoSlugField(editable=False, populate_from='title', unique=True)), ('slug', autoslug.fields.AutoSlugField(editable=False, populate_from='title', unique=True)),
('nb_player_min', models.PositiveSmallIntegerField(verbose_name='nombre de joueur·se·s minimum')), ('nb_player_min', models.PositiveSmallIntegerField(verbose_name='nombre de joueur·se·s minimum')),
('nb_player_max', models.PositiveSmallIntegerField(verbose_name='nombre de joueur·se·s maximum')), ('nb_player_max', models.PositiveSmallIntegerField(verbose_name='nombre de joueur·se·s maximum')),
@ -41,7 +42,7 @@ class Migration(migrations.Migration):
('illustrator', models.CharField(blank=True, max_length=256, verbose_name='illustrateur·trice')), ('illustrator', models.CharField(blank=True, max_length=256, verbose_name='illustrateur·trice')),
('editor', models.CharField(blank=True, max_length=256, verbose_name='éditeur')), ('editor', models.CharField(blank=True, max_length=256, verbose_name='éditeur')),
('description', models.TextField(blank=True, verbose_name='description')), ('description', models.TextField(blank=True, verbose_name='description')),
('image', models.ImageField(blank=True, upload_to='game_img/', verbose_name='image')), ('image', models.ImageField(blank=True, help_text="L'image doit peser 512 Kio au maximum", upload_to='game_img/', validators=[website.validators.MaxFileSizeValidator(512)], verbose_name='image')),
('missing_elements', models.TextField(blank=True, verbose_name='pièces manquantes')), ('missing_elements', models.TextField(blank=True, verbose_name='pièces manquantes')),
('category', models.ForeignKey(on_delete=django.db.models.deletion.RESTRICT, to='inventory.category', verbose_name='catégorie')), ('category', models.ForeignKey(on_delete=django.db.models.deletion.RESTRICT, to='inventory.category', verbose_name='catégorie')),
], ],
@ -55,7 +56,7 @@ class Migration(migrations.Migration):
name='Tag', name='Tag',
fields=[ fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=256, verbose_name='nom')), ('name', models.CharField(max_length=256, unique=True, verbose_name='nom')),
('slug', autoslug.fields.AutoSlugField(editable=False, populate_from='name', unique=True)), ('slug', autoslug.fields.AutoSlugField(editable=False, populate_from='name', unique=True)),
], ],
options={ options={

View file

@ -2,11 +2,12 @@ from django.db import models
from django.urls import reverse from django.urls import reverse
from django.core.exceptions import ValidationError from django.core.exceptions import ValidationError
from autoslug import AutoSlugField from autoslug import AutoSlugField
from website.validators import MaxFileSizeValidator
from comments.models import AbstractComment from comments.models import AbstractComment
class Category(models.Model): class Category(models.Model):
name = models.CharField(max_length=256, verbose_name="nom") name = models.CharField(max_length=256, verbose_name="nom", unique=True)
slug = AutoSlugField(populate_from="name", unique=True) slug = AutoSlugField(populate_from="name", unique=True)
class Meta: class Meta:
@ -21,7 +22,7 @@ class Category(models.Model):
class Tag(models.Model): class Tag(models.Model):
name = models.CharField(max_length=256, verbose_name="nom") name = models.CharField(max_length=256, verbose_name="nom", unique=True)
slug = AutoSlugField(populate_from="name", unique=True) slug = AutoSlugField(populate_from="name", unique=True)
class Meta: class Meta:
@ -35,8 +36,9 @@ class Tag(models.Model):
class Game(models.Model): class Game(models.Model):
title = models.CharField(verbose_name="titre", max_length=256) title = models.CharField(verbose_name="titre du jeu", max_length=256, unique=True)
slug = AutoSlugField(populate_from="title", unique=True) slug = AutoSlugField(populate_from="title", unique=True)
nb_player_min = models.PositiveSmallIntegerField( nb_player_min = models.PositiveSmallIntegerField(
verbose_name="nombre de joueur·se·s minimum" verbose_name="nombre de joueur·se·s minimum"
) )
@ -52,6 +54,7 @@ class Game(models.Model):
duration = models.CharField( duration = models.CharField(
max_length=256, blank=True, verbose_name="durée de partie" max_length=256, blank=True, verbose_name="durée de partie"
) )
game_designer = models.CharField( game_designer = models.CharField(
max_length=256, blank=True, verbose_name="game designer" max_length=256, blank=True, verbose_name="game designer"
) )
@ -59,12 +62,21 @@ class Game(models.Model):
max_length=256, blank=True, verbose_name="illustrateur·trice" max_length=256, blank=True, verbose_name="illustrateur·trice"
) )
editor = models.CharField(max_length=256, blank=True, verbose_name="éditeur") editor = models.CharField(max_length=256, blank=True, verbose_name="éditeur")
description = models.TextField(blank=True, verbose_name="description")
category = models.ForeignKey( category = models.ForeignKey(
Category, on_delete=models.RESTRICT, verbose_name="catégorie" Category, on_delete=models.RESTRICT, verbose_name="catégorie"
) )
tags = models.ManyToManyField(Tag, blank=True, verbose_name="tags") tags = models.ManyToManyField(Tag, blank=True, verbose_name="tags")
image = models.ImageField(upload_to="game_img/", blank=True, verbose_name="image")
description = models.TextField(blank=True, verbose_name="description")
image = models.ImageField(
upload_to="game_img/",
blank=True,
verbose_name="image",
help_text="L'image doit peser 512 Kio au maximum",
validators=[MaxFileSizeValidator(512)],
)
missing_elements = models.TextField(blank=True, verbose_name="pièces manquantes") missing_elements = models.TextField(blank=True, verbose_name="pièces manquantes")
class Meta: class Meta:
@ -79,7 +91,7 @@ class Game(models.Model):
if self.nb_player_min > self.nb_player_max: if self.nb_player_min > self.nb_player_max:
raise ValidationError( raise ValidationError(
{ {
"nb_player_max": "Le nombre de joueur·se·s maximum doit être supérieur au nombre de joueurs minimum" "nb_player_max": "Le nombre de joueur·se·s maximum doit être supérieur au nombre de joueur·se·s minimum"
} }
) )

28
website/validators.py Normal file
View file

@ -0,0 +1,28 @@
from django.core.exceptions import ValidationError
from django.utils.deconstruct import deconstructible
@deconstructible
class MaxFileSizeValidator:
"""
Reject all the files stored in a FileField (or ImageField) that are too heavy.
The size limit is given in Kio.
"""
def __init__(self, size_limit):
self.size_limit = size_limit
def __call__(self, value):
if value.size > self.size_limit * 1024:
raise ValidationError(
"La taille du fichier doit être inférieure à {} Kio".format(
self.size_limit
),
code="file_too_big",
)
def __eq__(self, other):
return (
isinstance(other, MaxFileSizeValidator)
and self.size_limit == other.size_limit
)