Use multi-file upload for "images" field

Closes #62
This commit is contained in:
Carl van Tonder 2018-05-29 23:14:36 -04:00
parent 8a8eccaeaa
commit 39949562c1
13 changed files with 207 additions and 31 deletions

View File

@ -1,9 +1,14 @@
from django import forms
from .models import File
from .models import File, ImageFile
class FileForm(forms.ModelForm):
class Meta:
model = File
exclude = ['user',]
class ImageFileForm(forms.ModelForm):
class Meta:
model = ImageFile
exclude = ['user',]

View File

@ -0,0 +1,36 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.6 on 2018-05-26 15:47
from __future__ import unicode_literals
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('files', '0002_file_user'),
]
operations = [
migrations.CreateModel(
name='ImageFile',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('file', models.FileField(upload_to='.')),
('caption', models.CharField(default=None, max_length=240, null=True, verbose_name='Image caption')),
('credit', models.CharField(default=None, max_length=240, null=True, verbose_name='Image credit')),
('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='imagefile', to=settings.AUTH_USER_MODEL)),
],
options={
'abstract': False,
},
),
migrations.AlterField(
model_name='file',
name='user',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='file', to=settings.AUTH_USER_MODEL),
),
]

View File

@ -0,0 +1,25 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.6 on 2018-05-30 03:08
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('files', '0003_auto_20180526_1547'),
]
operations = [
migrations.AlterField(
model_name='imagefile',
name='caption',
field=models.CharField(blank=True, default=None, max_length=240, null=True, verbose_name='Image caption'),
),
migrations.AlterField(
model_name='imagefile',
name='credit',
field=models.CharField(blank=True, default=None, max_length=240, null=True, verbose_name='Image credit'),
),
]

View File

@ -1,5 +1,6 @@
from django.contrib.auth.models import User
from django.db import models
from django.utils.translation import ugettext as _
from apps.map.models import CaseStudy, CaseStudyDraft
@ -9,7 +10,7 @@ class BaseFile(models.Model):
upload_to='.',
)
user = models.ForeignKey(
User, related_name='files'
User, related_name='%(class)s'
)
class Meta:
@ -21,3 +22,21 @@ class BaseFile(models.Model):
class File(BaseFile):
pass
class ImageFile(BaseFile):
caption = models.CharField(
verbose_name=_("Image caption"),
max_length=240,
default=None,
null=True,
blank=True,
)
credit = models.CharField(
verbose_name=_("Image credit"),
max_length=240,
default=None,
null=True,
blank=True,
)

View File

@ -213,6 +213,9 @@ class MultipleFilesWidget {
}
$(function() {
window.images = new MultipleFilesWidget(
document.querySelector('[data-field=images_files]')
)
window.official_project_documents = new MultipleFilesWidget(
document.querySelector('[data-field=official_project_documents_files]')
)

View File

@ -1,10 +1,11 @@
from django.conf.urls import url
from .views import FileUploadView, FileDeleteView
from .views import FileUploadView, FileDeleteView, ImageFileUploadView
app_name = 'files'
urlpatterns = [
url(r'^upload/$', FileUploadView.as_view(), name='upload'),
url(r'^upload/image/$', ImageFileUploadView.as_view(), name='upload'),
url(r'^delete/(?P<pk>\d+)/$', FileDeleteView.as_view(), name='delete'),
]

View File

@ -4,8 +4,9 @@ from django.http import JsonResponse
from django.shortcuts import render
from django.views.generic import FormView, DetailView
from .forms import FileForm
from .models import File
from .forms import ImageFileForm, FileForm
from .models import ImageFile, File
class FileUploadView(LoginRequiredMixin, FormView):
model = File
@ -26,6 +27,11 @@ class FileUploadView(LoginRequiredMixin, FormView):
return JsonResponse({'is_valid': False, 'errors': form.errors})
class ImageFileUploadView(FileUploadView):
model = ImageFile
form_class = ImageFileForm
class FileDeleteView(LoginRequiredMixin, DetailView):
model = File

View File

@ -9,7 +9,7 @@ from crispy_forms.bootstrap import Tab, TabHolder, PrependedText, FormActions
from dal import autocomplete
from leaflet.forms.widgets import LeafletWidget
from apps.files.models import File
from apps.files.models import File, ImageFile
from .models import CaseStudy, SpatialRefSys
from .widgets import CommaSeparatedTextInput
@ -71,9 +71,6 @@ class ShortCaseStudyForm(BaseCaseStudyForm):
'project_status',
'synopsis',
'full_description',
'image',
'image_caption',
'image_credit',
'video',
'media_coverage_mainstream',
'media_coverage_independent',
@ -88,6 +85,19 @@ class BootstrapClearableFileInput(forms.ClearableFileInput):
class LongCaseStudyForm(BaseCaseStudyForm):
"""Long version of the CaseStudy form."""
images = forms.FileField(
widget=BootstrapClearableFileInput(attrs={
'url': reverse_lazy('files:upload'),
'field': 'images_files',
}), required=False
)
images_files = forms.ModelMultipleChoiceField(
queryset=ImageFile.objects.all(),
widget=CommaSeparatedTextInput(),
required=True
)
official_project_documents = forms.FileField(
widget=BootstrapClearableFileInput(attrs={
'url': reverse_lazy('files:upload'),
@ -201,9 +211,8 @@ class LongCaseStudyForm(BaseCaseStudyForm):
'project_status',
'synopsis',
'full_description',
'image',
'image_caption',
'image_credit',
'images',
'images_files',
'video',
'video_caption',
'video_credit',

View File

@ -0,0 +1,21 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.6 on 2018-05-26 15:47
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('files', '0003_auto_20180526_1547'),
('map', '0064_auto_20180526_1536'),
]
operations = [
migrations.AddField(
model_name='casestudy',
name='images',
field=models.ManyToManyField(blank=True, related_name='image_for', to='files.ImageFile', verbose_name='Images'),
),
]

View File

@ -0,0 +1,36 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.6 on 2018-05-26 15:48
from __future__ import unicode_literals
from django.db import migrations
def copy_images(apps, schema_editor):
CaseStudy = apps.get_model('map', 'CaseStudy')
ImageFile = apps.get_model('files', 'ImageFile')
User = apps.get_model('auth', 'User')
for case_study in CaseStudy.objects.all():
author = case_study.author
if author is None:
author = User.objects.get(username='root')
imagefile = ImageFile(
file=case_study.image,
caption=case_study.image_caption,
credit=case_study.image_credit,
user=author
)
imagefile.save()
case_study.images.add(imagefile)
class Migration(migrations.Migration):
dependencies = [
('map', '0065_casestudy_images'),
]
operations = [
migrations.RunPython(copy_images, migrations.RunPython.noop),
]

View File

@ -0,0 +1,27 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.6 on 2018-05-29 05:20
from __future__ import unicode_literals
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('map', '0066_copy_images_to_imagefiles'),
]
operations = [
migrations.RemoveField(
model_name='casestudy',
name='image',
),
migrations.RemoveField(
model_name='casestudy',
name='image_caption',
),
migrations.RemoveField(
model_name='casestudy',
name='image_credit',
),
]

View File

@ -442,25 +442,12 @@ class CaseStudy(models.Model):
blank=True
)
# 1.15.1
image = models.ImageField(
verbose_name=_("Image")
)
# 1.15.2
image_caption = models.CharField(
verbose_name=_("Image caption"),
max_length=240,
default=None,
null=True,
)
# 1.15.3
image_credit = models.CharField(
verbose_name=_("Image credit(s)"),
max_length=240,
default=None,
null=True,
# 1.15.1, 1.15.2, 1.15.3
images = models.ManyToManyField(
'files.ImageFile',
related_name='image_for',
verbose_name=_("Images"),
blank=True
)
# 1.16.1

View File

@ -63,6 +63,7 @@ class BaseForm(LoginRequiredMixin, CreateView):
form.cleaned_data.pop('official_project_documents', None)
form.cleaned_data.pop('other_documents', None)
form.cleaned_data.pop('shapefiles', None)
form.cleaned_data.pop('images', None)
self.object = form.save()