Add unsplash model for storing images

Not wired in quite yet
This commit is contained in:
Jake Howard 2022-07-12 09:32:05 +01:00
parent ae4e24481e
commit 382853a384
Signed by: jake
GPG key ID: 57AFB45680EDD477
9 changed files with 115 additions and 1 deletions

View file

@ -7,3 +7,4 @@ isort==5.10.1
black==22.3.0 black==22.3.0
django-browser-reload==1.6.0 django-browser-reload==1.6.0
django-debug-toolbar==3.4.0 django-debug-toolbar==3.4.0
types-requests==2.27.1

View file

@ -6,3 +6,4 @@ pygments==2.12.0
beautifulsoup4==4.9.3 beautifulsoup4==4.9.3
lxml==4.9.0 lxml==4.9.0
more-itertools==8.13.0 more-itertools==8.13.0
requests==2.27.1

View file

View file

@ -0,0 +1,32 @@
# Generated by Django 4.0.5 on 2022-07-12 08:22
from django.db import migrations, models
class Migration(migrations.Migration):
initial = True
dependencies = [] # type: ignore
operations = [
migrations.CreateModel(
name="UnsplashPhoto",
fields=[
(
"id",
models.AutoField(
auto_created=True,
primary_key=True,
serialize=False,
verbose_name="ID",
),
),
(
"unsplash_id",
models.CharField(db_index=True, max_length=11, unique=True),
),
("data", models.JSONField()),
],
),
]

View file

@ -0,0 +1,6 @@
from django.db import models
class UnsplashPhoto(models.Model):
unsplash_id = models.CharField(unique=True, max_length=11, db_index=True)
data = models.JSONField()

View file

@ -0,0 +1,19 @@
import requests
from django.conf import settings
def get_unsplash_photo(image_id: str) -> dict:
response = requests.get(
f"https://api.unsplash.com/photos/{image_id}",
headers={
"Accept-Version": "v1",
"Authorization": f"Client-ID {settings.UNSPLASH_CLIENT_ID}",
},
)
if response.status_code == 404:
raise ValueError(f"Unknown image {image_id}")
response.raise_for_status()
return response.json()

View file

@ -0,0 +1,48 @@
from typing import Type
from django.core.exceptions import ValidationError
from wagtail.admin.forms.models import WagtailAdminModelForm
from wagtail.contrib.modeladmin.options import ModelAdmin, modeladmin_register
from wagtail.contrib.modeladmin.views import CreateView
from .models import UnsplashPhoto
from .utils import get_unsplash_photo
class UnsplashPhotoCreateView(CreateView):
def get_form_class(self) -> WagtailAdminModelForm:
"""
Modify form class to validate unsplash id and save data to model1
"""
EditHandlerForm: Type[
WagtailAdminModelForm
] = self.edit_handler.get_form_class()
class CreateFormClass(EditHandlerForm): # type: ignore[valid-type,misc]
def clean(self) -> None:
cleaned_data = super().clean()
try:
self._unsplash_photo_data = get_unsplash_photo(
cleaned_data["unsplash_id"]
)
except ValueError as e:
raise ValidationError(str(e))
def save(self, commit: bool = True) -> UnsplashPhoto:
self.instance.data = self._unsplash_photo_data
return super().save(commit)
return CreateFormClass
@modeladmin_register
class UnsplashPhotoAdmin(ModelAdmin):
model = UnsplashPhoto
list_display = ["unsplash_id", "description"]
form_fields_exclude = ["data"]
search_fields = ["unsplash_id", "data__description"]
create_view_class = UnsplashPhotoCreateView
menu_icon = "image"
def description(self, instance: UnsplashPhoto) -> str:
return instance.data["description"]

View file

@ -4,7 +4,11 @@ import environ
BASE_DIR = Path(__file__).parent.parent BASE_DIR = Path(__file__).parent.parent
env = environ.Env(DEBUG=(bool, False), BASE_HOSTNAME=(str, "example.com")) env = environ.Env(
DEBUG=(bool, False),
BASE_HOSTNAME=(str, "example.com"),
UNSPLASH_CLIENT_ID=(str, ""),
)
# Read local secrets # Read local secrets
environ.Env.read_env(BASE_DIR / ".env") environ.Env.read_env(BASE_DIR / ".env")
@ -25,6 +29,7 @@ INSTALLED_APPS = [
"website.blog", "website.blog",
"website.images", "website.images",
"website.contrib.code_block", "website.contrib.code_block",
"website.contrib.unsplash",
"wagtail.contrib.forms", "wagtail.contrib.forms",
"wagtail.contrib.redirects", "wagtail.contrib.redirects",
"wagtail.contrib.modeladmin", "wagtail.contrib.modeladmin",
@ -153,6 +158,8 @@ WAGTAILEMBEDS_FINDERS = [
}, },
] ]
UNSPLASH_CLIENT_ID = env("UNSPLASH_CLIENT_ID")
if DEBUG: if DEBUG:
# Add django-browser-reload # Add django-browser-reload