Add chooser for unsplash photos
It doesn't show images, yet
This commit is contained in:
parent
382853a384
commit
72dc3cc4ea
10 changed files with 175 additions and 1 deletions
|
@ -7,3 +7,4 @@ 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
|
requests==2.27.1
|
||||||
|
wagtail-generic-chooser==0.4.1
|
||||||
|
|
|
@ -0,0 +1,35 @@
|
||||||
|
# Generated by Django 4.0.5 on 2022-07-12 13:04
|
||||||
|
|
||||||
|
import django.db.models.deletion
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
("unsplash", "0001_initial"),
|
||||||
|
("blog", "0009_alter_bloglistpage_body_alter_blogpostpage_body"),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name="bloglistpage",
|
||||||
|
name="hero_unsplash_photo",
|
||||||
|
field=models.ForeignKey(
|
||||||
|
blank=True,
|
||||||
|
null=True,
|
||||||
|
on_delete=django.db.models.deletion.SET_NULL,
|
||||||
|
to="unsplash.unsplashphoto",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name="blogpostpage",
|
||||||
|
name="hero_unsplash_photo",
|
||||||
|
field=models.ForeignKey(
|
||||||
|
blank=True,
|
||||||
|
null=True,
|
||||||
|
on_delete=django.db.models.deletion.SET_NULL,
|
||||||
|
to="unsplash.unsplashphoto",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
]
|
|
@ -0,0 +1,35 @@
|
||||||
|
# Generated by Django 4.0.5 on 2022-07-12 13:04
|
||||||
|
|
||||||
|
import django.db.models.deletion
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
("unsplash", "0001_initial"),
|
||||||
|
("common", "0010_alter_contentpage_body_alter_listingpage_body"),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name="contentpage",
|
||||||
|
name="hero_unsplash_photo",
|
||||||
|
field=models.ForeignKey(
|
||||||
|
blank=True,
|
||||||
|
null=True,
|
||||||
|
on_delete=django.db.models.deletion.SET_NULL,
|
||||||
|
to="unsplash.unsplashphoto",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name="listingpage",
|
||||||
|
name="hero_unsplash_photo",
|
||||||
|
field=models.ForeignKey(
|
||||||
|
blank=True,
|
||||||
|
null=True,
|
||||||
|
on_delete=django.db.models.deletion.SET_NULL,
|
||||||
|
to="unsplash.unsplashphoto",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
]
|
|
@ -10,6 +10,7 @@ from wagtail.images import get_image_model_string
|
||||||
from wagtail.models import Page
|
from wagtail.models import Page
|
||||||
|
|
||||||
from website.common.utils import count_words
|
from website.common.utils import count_words
|
||||||
|
from website.contrib.unsplash.widgets import UnsplashPhotoChooser
|
||||||
|
|
||||||
from .streamfield import add_heading_anchors, get_blocks, get_content_html
|
from .streamfield import add_heading_anchors, get_blocks, get_content_html
|
||||||
from .utils import TocEntry, extract_text, get_table_of_contents, truncate_string
|
from .utils import TocEntry, extract_text, get_table_of_contents, truncate_string
|
||||||
|
@ -39,11 +40,15 @@ class BaseContentMixin(models.Model):
|
||||||
hero_image = models.ForeignKey(
|
hero_image = models.ForeignKey(
|
||||||
get_image_model_string(), null=True, blank=True, on_delete=models.SET_NULL
|
get_image_model_string(), null=True, blank=True, on_delete=models.SET_NULL
|
||||||
)
|
)
|
||||||
|
hero_unsplash_photo = models.ForeignKey(
|
||||||
|
"unsplash.UnsplashPhoto", null=True, blank=True, on_delete=models.SET_NULL
|
||||||
|
)
|
||||||
body = StreamField(get_blocks(), blank=True, use_json_field=True)
|
body = StreamField(get_blocks(), blank=True, use_json_field=True)
|
||||||
|
|
||||||
content_panels = [
|
content_panels = [
|
||||||
FieldPanel("subtitle"),
|
FieldPanel("subtitle"),
|
||||||
FieldPanel("hero_image"),
|
FieldPanel("hero_image"),
|
||||||
|
FieldPanel("hero_unsplash_photo", widget=UnsplashPhotoChooser),
|
||||||
FieldPanel("body"),
|
FieldPanel("body"),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
|
@ -4,3 +4,6 @@ from django.db import models
|
||||||
class UnsplashPhoto(models.Model):
|
class UnsplashPhoto(models.Model):
|
||||||
unsplash_id = models.CharField(unique=True, max_length=11, db_index=True)
|
unsplash_id = models.CharField(unique=True, max_length=11, db_index=True)
|
||||||
data = models.JSONField()
|
data = models.JSONField()
|
||||||
|
|
||||||
|
def get_description(self) -> str:
|
||||||
|
return self.data["description"]
|
||||||
|
|
31
website/contrib/unsplash/templates/unsplash/results.html
Normal file
31
website/contrib/unsplash/templates/unsplash/results.html
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
{# Adapted from generic_chooser/_results.html #}
|
||||||
|
|
||||||
|
{% load i18n %}
|
||||||
|
|
||||||
|
<table class="listing">
|
||||||
|
<col />
|
||||||
|
<col />
|
||||||
|
<col width="16%" />
|
||||||
|
<thead>
|
||||||
|
<tr class="table-headers">
|
||||||
|
<th>{% trans "Unsplash ID" %}</th>
|
||||||
|
<th>{% trans "Description" %}</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{% for row in rows %}
|
||||||
|
<tr>
|
||||||
|
<td class="title">
|
||||||
|
<h2><a class="item-choice" href="{{ row.choose_url }}">{{ row.item.unsplash_id }}</a></h2>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
{{ row.item.get_description }}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
{% if is_paginated %}
|
||||||
|
{% include "generic_chooser/_ajax_pagination_nav.html" with items=page %}
|
||||||
|
{% endif %}
|
39
website/contrib/unsplash/views.py
Normal file
39
website/contrib/unsplash/views.py
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
from generic_chooser.views import (
|
||||||
|
ModelChooserCreateTabMixin,
|
||||||
|
ModelChooserMixin,
|
||||||
|
ModelChooserViewSet,
|
||||||
|
)
|
||||||
|
|
||||||
|
from .models import UnsplashPhoto
|
||||||
|
|
||||||
|
|
||||||
|
class UnsplashPhotoCreateTabMixin(ModelChooserCreateTabMixin):
|
||||||
|
"""
|
||||||
|
Don't allow creation during creation
|
||||||
|
"""
|
||||||
|
|
||||||
|
def get_form_class(self) -> None:
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
class UnsplashPhotoChooserMixin(ModelChooserMixin):
|
||||||
|
results_template = "unsplash/results.html"
|
||||||
|
|
||||||
|
def get_object_string(self, instance: UnsplashPhoto) -> str:
|
||||||
|
return instance.unsplash_id
|
||||||
|
|
||||||
|
def get_row_data(self, item: UnsplashPhoto) -> dict:
|
||||||
|
item_data = super().get_row_data(item)
|
||||||
|
item_data["item"] = item
|
||||||
|
return item_data
|
||||||
|
|
||||||
|
|
||||||
|
class UnsplashPhotoChooserViewSet(ModelChooserViewSet):
|
||||||
|
icon = "image"
|
||||||
|
model = UnsplashPhoto
|
||||||
|
page_title = "Choose a photo"
|
||||||
|
per_page = 10
|
||||||
|
order_by = "unsplash_id"
|
||||||
|
fields = ["unsplash_id", "data"]
|
||||||
|
create_tab_mixin_class = UnsplashPhotoCreateTabMixin
|
||||||
|
chooser_mixin_class = UnsplashPhotoChooserMixin
|
|
@ -4,9 +4,11 @@ from django.core.exceptions import ValidationError
|
||||||
from wagtail.admin.forms.models import WagtailAdminModelForm
|
from wagtail.admin.forms.models import WagtailAdminModelForm
|
||||||
from wagtail.contrib.modeladmin.options import ModelAdmin, modeladmin_register
|
from wagtail.contrib.modeladmin.options import ModelAdmin, modeladmin_register
|
||||||
from wagtail.contrib.modeladmin.views import CreateView
|
from wagtail.contrib.modeladmin.views import CreateView
|
||||||
|
from wagtail.core import hooks
|
||||||
|
|
||||||
from .models import UnsplashPhoto
|
from .models import UnsplashPhoto
|
||||||
from .utils import get_unsplash_photo
|
from .utils import get_unsplash_photo
|
||||||
|
from .views import UnsplashPhotoChooserViewSet
|
||||||
|
|
||||||
|
|
||||||
class UnsplashPhotoCreateView(CreateView):
|
class UnsplashPhotoCreateView(CreateView):
|
||||||
|
@ -45,4 +47,11 @@ class UnsplashPhotoAdmin(ModelAdmin):
|
||||||
menu_icon = "image"
|
menu_icon = "image"
|
||||||
|
|
||||||
def description(self, instance: UnsplashPhoto) -> str:
|
def description(self, instance: UnsplashPhoto) -> str:
|
||||||
return instance.data["description"]
|
return instance.get_description()
|
||||||
|
|
||||||
|
|
||||||
|
@hooks.register("register_admin_viewset")
|
||||||
|
def register_person_chooser_viewset() -> UnsplashPhotoChooserViewSet:
|
||||||
|
return UnsplashPhotoChooserViewSet(
|
||||||
|
"unsplash_photo_chooser", url_prefix="unsplash-photo-chooser"
|
||||||
|
)
|
||||||
|
|
15
website/contrib/unsplash/widgets.py
Normal file
15
website/contrib/unsplash/widgets.py
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
from generic_chooser.widgets import AdminChooser
|
||||||
|
|
||||||
|
from .models import UnsplashPhoto
|
||||||
|
|
||||||
|
|
||||||
|
class UnsplashPhotoChooser(AdminChooser):
|
||||||
|
choose_one_text = "Choose a photo"
|
||||||
|
choose_another_text = "Choose another photo"
|
||||||
|
show_edit_link = False
|
||||||
|
show_create_link = False
|
||||||
|
model = UnsplashPhoto
|
||||||
|
choose_modal_url_name = "unsplash_photo_chooser:choose"
|
||||||
|
|
||||||
|
def get_title(self, instance: UnsplashPhoto) -> str:
|
||||||
|
return instance.unsplash_id
|
|
@ -44,6 +44,7 @@ INSTALLED_APPS = [
|
||||||
"wagtail",
|
"wagtail",
|
||||||
"modelcluster",
|
"modelcluster",
|
||||||
"taggit",
|
"taggit",
|
||||||
|
"generic_chooser",
|
||||||
"django.contrib.admin",
|
"django.contrib.admin",
|
||||||
"django.contrib.auth",
|
"django.contrib.auth",
|
||||||
"django.contrib.contenttypes",
|
"django.contrib.contenttypes",
|
||||||
|
|
Loading…
Reference in a new issue