Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ venv/
*.JPEG
/static/lightbox/images/
/static/ckeditor/ckeditor/skins/
apps/*/migrations/*.py
!**/migrations/__init__.py
# apps/*/migrations/*.py
# !**/migrations/__init__.py
.DS_Store
db.sqlite3
.idea/
Expand Down
89 changes: 89 additions & 0 deletions apps/blog/migrations/0001_initial.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
# Generated by Django 5.2 on 2025-05-25 21:49

import django.db.models.deletion
import django.utils.timezone
import taggit.managers
from django.conf import settings
from django.db import migrations, models


class Migration(migrations.Migration):

initial = True

dependencies = [
(
"taggit",
"0006_rename_taggeditem_content_type_object_id_taggit_tagg_content_8fc721_idx",
),
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
]

operations = [
migrations.CreateModel(
name="Contact",
fields=[
(
"id",
models.BigAutoField(
auto_created=True,
primary_key=True,
serialize=False,
verbose_name="ID",
),
),
("name", models.CharField(default="", max_length=255)),
("email", models.EmailField(max_length=254)),
("subject", models.CharField(max_length=255)),
("message", models.TextField()),
],
),
migrations.CreateModel(
name="Post",
fields=[
(
"id",
models.BigAutoField(
auto_created=True,
primary_key=True,
serialize=False,
verbose_name="ID",
),
),
("title", models.CharField(max_length=50, unique=True)),
("slug", models.SlugField(unique=True)),
("updated_on", models.DateField(default=django.utils.timezone.now)),
("created_on", models.DateField(default=django.utils.timezone.now)),
("content", models.TextField()),
(
"status",
models.IntegerField(
choices=[(0, "Draft"), (1, "Publish")], default=0
),
),
("thumb", models.ImageField(blank=True, upload_to="")),
(
"author",
models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
related_name="blog_posts",
to=settings.AUTH_USER_MODEL,
),
),
(
"tag",
taggit.managers.TaggableManager(
help_text="A comma-separated list of tags.",
through="taggit.TaggedItem",
to="taggit.Tag",
verbose_name="Tags",
),
),
],
options={
"verbose_name": "Blog",
"verbose_name_plural": "Blogs",
"ordering": ["-created_on"],
},
),
]
104 changes: 93 additions & 11 deletions apps/gallery/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,24 @@
Author: Jared Paubel
Version: 0.1
"""
from django.utils.text import slugify
from django.urls import path, reverse
from django.shortcuts import render, redirect
from django.contrib import messages
from django import forms
from django.utils.translation import gettext_lazy as _
from photologue.forms import UploadZipForm
from zipfile import ZipFile
from io import BytesIO
from django.contrib import admin
from apps.gallery.models import (
CountryAlbum,
CityGallery,
CityPhoto,
City,
Country,
PhotoGallery
)
from photologue.admin import (
PhotoAdmin as BasePhotoAdmin
Country
)
from photologue.admin import PhotoAdmin


class CityGalleryInline(admin.StackedInline):
Expand Down Expand Up @@ -58,12 +64,88 @@ def get_model_perms(self, request):
return {}


class CityPhotoZipUploadForm(UploadZipForm):
"""Form for uploading a zip file as CityPhoto objects."""
gallery = forms.ModelChoiceField(
queryset=CityGallery.objects.select_related('city', 'album__country').all(),
label=_("City Gallery"),
required=True
)
city = forms.ModelChoiceField(
queryset=City.objects.all(),
label=_("City"),
required=False
)
country = forms.ModelChoiceField(
queryset=Country.objects.all(),
label=_("Country"),
required=False
)


@admin.register(CityPhoto)
class CityPhotoAdmin(BasePhotoAdmin):
class CityPhotoAdmin(PhotoAdmin):
autocomplete_fields = ['country', 'city']

def get_model_perms(self, request):
"""
Return empty perms dict, hiding the model from admin index.
"""
return {}
def get_urls(self):
urls = super().get_urls()
custom_urls = [
path(
'upload_zip/',
self.admin_site.admin_view(self.upload_zip),
name='gallery_cityphoto_upload_zip',
),
]
return custom_urls + urls

def changelist_view(self, request, extra_context=None):
if extra_context is None:
extra_context = {}
extra_context['upload_zip_url'] = reverse(
'admin:gallery_cityphoto_upload_zip'
)
return super().changelist_view(request, extra_context=extra_context)

def upload_zip(self, request):
opts = self.model._meta
app_label = opts.app_label

if request.method == 'POST':
form = CityPhotoZipUploadForm(request.POST, request.FILES)
if form.is_valid():
city = form.cleaned_data.get('city')
country = form.cleaned_data.get('country')
zip_file = request.FILES['zip_file']
with ZipFile(zip_file) as archive:
for idx, filename in enumerate(
archive.namelist(),
start=1
):
if filename.lower().endswith(
('.jpg', '.jpeg', '.png', '.gif')
):
data = archive.read(filename)
photo = CityPhoto()
photo.title = "{} {}".format(city.name, idx)
photo.image.save(filename, BytesIO(data))
photo.city = city
photo.country = country
photo.save()
messages.success(request, _("Photos uploaded successfully."))
return redirect('admin:gallery_cityphoto_changelist')
else:
form = CityPhotoZipUploadForm()

context = {
'form': form,
'opts': opts,
'app_label': app_label,
'has_change_permission': self.has_change_permission(request),
}
return render(request, 'admin/gallery/upload_zip.html', context)

# def get_model_perms(self, request):
# """
# Return empty perms dict, hiding the model from admin index.
# """
# return {}
41 changes: 41 additions & 0 deletions apps/gallery/migrations/0001_initial.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# Generated by Django 5.2 on 2025-05-22 20:54

from django.db import migrations, models


class Migration(migrations.Migration):

initial = True

dependencies = [
("photologue", "0013_alter_watermark_image"),
]

operations = [
migrations.CreateModel(
name="PhotoGallery",
fields=[
(
"id",
models.BigAutoField(
auto_created=True,
primary_key=True,
serialize=False,
verbose_name="ID",
),
),
("country", models.CharField(max_length=199)),
("content", models.TextField()),
(
"slug",
models.SlugField(allow_unicode=True, blank=True, max_length=250),
),
("galleries", models.ManyToManyField(to="photologue.gallery")),
],
options={
"verbose_name": "Gallery",
"verbose_name_plural": "Galleries",
"ordering": ["country"],
},
),
]
Loading