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
|
||||
more-itertools==8.13.0
|
||||
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 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 .utils import TocEntry, extract_text, get_table_of_contents, truncate_string
|
||||
|
@ -39,11 +40,15 @@ class BaseContentMixin(models.Model):
|
|||
hero_image = models.ForeignKey(
|
||||
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)
|
||||
|
||||
content_panels = [
|
||||
FieldPanel("subtitle"),
|
||||
FieldPanel("hero_image"),
|
||||
FieldPanel("hero_unsplash_photo", widget=UnsplashPhotoChooser),
|
||||
FieldPanel("body"),
|
||||
]
|
||||
|
||||
|
|
|
@ -4,3 +4,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()
|
||||
|
||||
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.contrib.modeladmin.options import ModelAdmin, modeladmin_register
|
||||
from wagtail.contrib.modeladmin.views import CreateView
|
||||
from wagtail.core import hooks
|
||||
|
||||
from .models import UnsplashPhoto
|
||||
from .utils import get_unsplash_photo
|
||||
from .views import UnsplashPhotoChooserViewSet
|
||||
|
||||
|
||||
class UnsplashPhotoCreateView(CreateView):
|
||||
|
@ -45,4 +47,11 @@ class UnsplashPhotoAdmin(ModelAdmin):
|
|||
menu_icon = "image"
|
||||
|
||||
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",
|
||||
"modelcluster",
|
||||
"taggit",
|
||||
"generic_chooser",
|
||||
"django.contrib.admin",
|
||||
"django.contrib.auth",
|
||||
"django.contrib.contenttypes",
|
||||
|
|
Loading…
Reference in a new issue