diff --git a/giza/admin.py b/giza/admin.py
index 1b1e40d..af3d405 100644
--- a/giza/admin.py
+++ b/giza/admin.py
@@ -4,7 +4,7 @@
from django.contrib.auth.admin import UserAdmin
from .forms import CustomUserCreationForm, CustomUserChangeForm
-from .models import CustomUser, Lesson, Topic, Collection
+from .models import CustomUser, Lesson, Topic, Collection, ElasticsearchItem
class CustomUserAdmin(UserAdmin):
add_form = CustomUserCreationForm
@@ -15,9 +15,17 @@ class CustomUserAdmin(UserAdmin):
(None, {'fields': ('full_name', 'bio', 'tagline', 'picture')}),
)
+
+class ElasticsearchItemInline(admin.TabularInline):
+ model = ElasticsearchItem
+
class CollectionAdmin(admin.ModelAdmin):
readonly_fields=('slug',)
+ inlines = [
+ ElasticsearchItemInline,
+ ]
+
class LessonAdmin(admin.ModelAdmin):
readonly_fields=('slug',)
diff --git a/giza/forms.py b/giza/forms.py
index 284f25a..cb28acf 100644
--- a/giza/forms.py
+++ b/giza/forms.py
@@ -2,7 +2,7 @@
from django.contrib.auth.forms import UserCreationForm, UserChangeForm
from tinymce.widgets import TinyMCE
-from .models import CustomUser
+from .models import CustomUser, Collection
class CustomUserCreationForm(UserCreationForm):
class Meta:
@@ -13,3 +13,9 @@ class CustomUserChangeForm(UserChangeForm):
class Meta:
model = CustomUser
fields = ('full_name', 'username', 'email',)
+
+class CollectionForm(forms.ModelForm):
+ title = forms.CharField(required=False, label="Name your new collection")
+ class Meta:
+ model = Collection
+ fields = ('title', )
diff --git a/giza/migrations/0005_auto_20210314_0551.py b/giza/migrations/0005_auto_20210314_0551.py
new file mode 100644
index 0000000..6f32866
--- /dev/null
+++ b/giza/migrations/0005_auto_20210314_0551.py
@@ -0,0 +1,27 @@
+# Generated by Django 2.2.12 on 2021-03-14 05:51
+
+from django.db import migrations, models
+import django.db.models.deletion
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('giza', '0004_lesson_summary'),
+ ]
+
+ operations = [
+ migrations.RemoveField(
+ model_name='collection',
+ name='items',
+ ),
+ migrations.CreateModel(
+ name='ElasticsearchItem',
+ fields=[
+ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('type', models.CharField(max_length=20)),
+ ('es_id', models.IntegerField()),
+ ('collection', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='items', to='giza.Collection')),
+ ],
+ ),
+ ]
diff --git a/giza/migrations/0006_collection_public.py b/giza/migrations/0006_collection_public.py
new file mode 100644
index 0000000..65cfb0b
--- /dev/null
+++ b/giza/migrations/0006_collection_public.py
@@ -0,0 +1,19 @@
+# Generated by Django 2.2.12 on 2021-04-15 13:56
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('giza', '0005_auto_20210314_0551'),
+ ]
+
+ operations = [
+ migrations.AddField(
+ model_name='collection',
+ name='public',
+ field=models.BooleanField(blank=True, default=False),
+ preserve_default=False,
+ ),
+ ]
diff --git a/giza/models.py b/giza/models.py
index 5935bb6..e4e09aa 100644
--- a/giza/models.py
+++ b/giza/models.py
@@ -1,6 +1,5 @@
from django.contrib.auth.models import AbstractUser
from django.db import models
-from django.contrib.postgres.fields import JSONField
from django.utils.text import slugify
from tinymce.models import HTMLField
@@ -13,12 +12,6 @@
(PRIVATE, 'Private'),
]
-EDITION = 'EDITION'
-TRANSLATION = 'TRANSLATION'
-CONTENT_TYPE_CHOICES = [
- (EDITION, 'Edition'),
- (TRANSLATION, 'Translation'),
-]
class CustomUser(AbstractUser):
@@ -79,18 +72,17 @@ def save(self, *args, **kwargs):
self.slug = self._get_unique_slug()
super().save(*args, **kwargs)
+
class Collection(models.Model):
title = models.CharField(max_length=256)
slug = models.SlugField(blank=True)
+ public = models.BooleanField(blank=True, default=False)
owners = models.ManyToManyField(
'CustomUser', related_name='owners', blank=True)
topics = models.ManyToManyField('Topic', related_name='collections_topics', blank=True)
picture = models.ImageField(
upload_to='images', blank=True)
- # possibly consider json field for this in the future
- items = models.TextField(blank=True)
-
def __str__(self):
return self.title
@@ -105,3 +97,12 @@ def _get_unique_slug(self):
def save(self, *args, **kwargs):
self.slug = self._get_unique_slug()
super().save(*args, **kwargs)
+
+
+class ElasticsearchItem(models.Model):
+ collection = models.ForeignKey(Collection, related_name='items', on_delete=models.CASCADE)
+ type = models.CharField(max_length=20)
+ es_id = models.IntegerField()
+
+ def __str__(self):
+ return "{}-{}".format(self.es_id, self.type)
diff --git a/giza/urls.py b/giza/urls.py
index 2eea868..2050546 100644
--- a/giza/urls.py
+++ b/giza/urls.py
@@ -15,6 +15,7 @@
"""
from django.conf.urls import url
from django.urls import path
+from django.conf.urls import include
from django.contrib import admin
from tms import views as tms_views
from search import views as search_views
@@ -34,7 +35,7 @@
url(r'^collections/user$', views.collections_user, name="collections_user"),
url(r'^collections/create$', views.collections_create, name="collections_create"),
url(r'^collections/(?P[\w-]+)$', views.collection, name="collection"),
- url(r'^collections/(?P[\w-]+)/edit$', views.collection, name="collection_edit"),
+ url(r'^collections/(?P[\w-]+)/edit$', views.collections_edit, name="collection_edit"),
url(r'^collections/$', views.collections, name="collections"),
url(r'^mygiza/$', views.mygiza, name="mygiza"),
@@ -47,6 +48,7 @@
url(r'^search-results/$', search_views.results, name='results'),
# auth
+ # TODO for password change/reset, implement django accounts auth
# path('accounts/', include('django.contrib.auth.urls')),
url('sign-up/', views.sign_up, name='sign_up'),
url('login/', views.user_login, name='login'),
diff --git a/giza/views.py b/giza/views.py
index 07b471e..bdaa2e4 100644
--- a/giza/views.py
+++ b/giza/views.py
@@ -17,8 +17,8 @@
from utils.elastic_backend import es, ES_INDEX
from utils.views_utils import CATEGORIES, FACETS_PER_CATEGORY, FIELDS_PER_CATEGORY
-from .forms import CustomUserCreationForm
-from .models import Collection, Lesson
+from .forms import CustomUserCreationForm, CollectionForm
+from .models import Collection, Lesson, ElasticsearchItem
RESULTS_SIZE = 20
@@ -245,7 +245,7 @@ def mygiza(request):
return render(request, 'pages/mygiza-landing.html')
def collections(request):
- collections = Collection.objects.all()
+ collections = Collection.objects.filter(public=True)
return render(request, 'pages/mygiza-allcollections.html', {
'collections': collections,
@@ -266,7 +266,40 @@ def collection(request, slug):
hits = []
search_term = request.GET.get('q', '')
- item_ids = collection.items.split(",")
+ query = {}
+
+ if collection.items.all():
+ query = {
+ 'bool': {
+ "should": [],
+ }
+ }
+ for elasticsearch_item in collection.items.all():
+ query['bool']['should'].append({
+ 'bool': {
+ 'must': [
+ {
+ 'term': {
+ "_type": elasticsearch_item.type,
+ }
+ },
+ {
+ 'term': {
+ "_id": elasticsearch_item.es_id,
+ }
+ },
+ ]
+ }
+ })
+ else:
+ # pass a query that will get no values returned
+ query = {
+ 'ids': {
+ 'type': '_doc',
+ 'values': []
+ }
+ }
+
categorystring = ""
current_category = request.GET.get('category', '')
current_subfacets = {}
@@ -291,11 +324,7 @@ def collection(request, slug):
body_query = {
"from": results_from,
"size": RESULTS_SIZE,
- "query": {
- "ids": {
- "values": item_ids,
- }
- },
+ "query": query,
"aggregations": {
"aggregation": {
"terms": {
@@ -323,12 +352,8 @@ def collection(request, slug):
search_results = es.search(index=ES_INDEX, body={
"from": results_from,
- "size": RESULTS_SIZE,
- "query": {
- "ids": {
- "values": item_ids,
- }
- },
+ "size": 10000,
+ "query": query,
"aggregations": {
"aggregation": {
"terms": {
@@ -399,11 +424,78 @@ def collection(request, slug):
def collections_create(request):
- return render(request, 'pages/mygiza-collection-edit.html')
+ # create a collection
+ if request.method == 'POST':
+ collection_form = CollectionForm(data=request.POST)
+
+ # save user
+ if collection_form.is_valid():
+ # create user
+ collection = collection_form.save()
+ collection.owners.add(request.user)
+ collection.save()
+
+ return redirect('/collections/{}'.format(collection.slug))
+
+ else:
+ messages.error(request, "Error creating collection.")
+
+ # show collection form
+ else:
+ collection_form = CollectionForm()
-def collections_edit(request):
+ return render(request, 'pages/mygiza-collection-edit.html', {
+ 'collection_form': collection_form,
+ })
+
+def collections_edit(request, slug):
+
+ # create a collection
+ if request.method == 'POST':
+ collection_form = CollectionForm(data=request.POST)
- return render(request, 'pages/mygiza-collection-edit.html')
+ # save user
+ if collection_form.is_valid():
+ # create user
+ collection = collection_form.save()
+ collection.save()
+
+ return redirect('/collections/{}'.format(collection.slug))
+
+ else:
+ messages.error(request, "Error creating collection.")
+
+ # show collection form
+ else:
+ collection = get_object_or_404(Collection, slug=slug)
+ collection_form = CollectionForm(collection)
+
+ # user does not own this collection, redirect to collections page
+ if not request.user in collection.owners.all():
+ return redirect('/collections/')
+
+ # handle adding new item id and type to collection
+ if request.GET.get('add_item_id') and request.GET.get('add_item_type'):
+ elasticsearch_item = ElasticsearchItem(
+ es_id=request.GET.get('add_item_id'),
+ type=request.GET.get('add_item_type'),
+ collection=collection
+ )
+ elasticsearch_item.save()
+ return redirect('/collections/{}'.format(collection.slug))
+
+ elif request.GET.get('remove_item_id') and request.GET.get('remove_item_type'):
+ elasticsearch_item = ElasticsearchItem.objects.filter(
+ es_id=request.GET.get('remove_item_id'),
+ type=request.GET.get('remove_item_type'),
+ collection=collection
+ )
+ elasticsearch_item.delete()
+ return redirect('/collections/{}'.format(collection.slug))
+
+ return render(request, 'pages/mygiza-collection-edit.html', {
+ 'collection_form': collection_form,
+ })
def lessons(request):
lessons = Lesson.objects.all()
diff --git a/templates/pages/full.html b/templates/pages/full.html
index d6d1cf8..0ca3202 100644
--- a/templates/pages/full.html
+++ b/templates/pages/full.html
@@ -29,6 +29,18 @@ {{ object.displaytext }}
diff --git a/templates/pages/mygiza-collection-edit.html b/templates/pages/mygiza-collection-edit.html
index 582272e..2c7daad 100644
--- a/templates/pages/mygiza-collection-edit.html
+++ b/templates/pages/mygiza-collection-edit.html
@@ -26,16 +26,11 @@
Create a new collection
Creating and editing collections is restricted to admin users currently. We hope to add this functionality in soon.
-
+ {{collection_form.as_p}}
- Create
+ Create
diff --git a/templates/pages/mygiza-collection.html b/templates/pages/mygiza-collection.html
index e3efca9..53ab04c 100644
--- a/templates/pages/mygiza-collection.html
+++ b/templates/pages/mygiza-collection.html
@@ -47,7 +47,7 @@
{% if user.is_superuser %}
- add
+ add
{% elif user.is_authenticated %}
add
{% else %}
@@ -60,16 +60,20 @@
@@ -190,68 +194,6 @@ Search Options
Start a new search
- {% if search_params %}
-
- {% for param in search_params %}
-
{{ param.1 }}:
-
- {% endfor %}
-
- {% endif %}
-
- {% if total > 0 %}
-
- {% endif %}
-
-
- {% for cat_name, cat_facets in sub_facets.items %}
- {% for facet_type in cat_facets %}
- {% for facet_title, facet_values in facet_type.items %}
- {% if facet_values %}
-
-
- {{facet_title}}:
-
-
-
- {% endif %}
- {% endfor %}
- {% endfor %}
- {% endfor %}
@@ -263,7 +205,11 @@
{{collection.title}}
Created by
{% for owner in collection.owners.all %}
- {{owner.full_name}}
+ {% if owner.full_name %}
+ {{owner.full_name}}
+ {% else %}
+ {{owner.username}}
+ {% endif %}
{% endfor %}
@@ -287,6 +233,7 @@
{{collection.title}}
{% for result in hits %}
+
+ {% if user in collection.owners.all %}
+
+ Remove
+
+ {% endif %}
+
{% empty %}
@@ -312,11 +266,7 @@ {{collection.title}}
There are no items in this collection yet.
- {% if user.is_superuser %}
- Add one.
- {% elif user.is_authenticated %}
- Add one.
- {% endif %}
+ Add one.
{% endfor %}
diff --git a/templates/partials/modals.html b/templates/partials/modals.html
index eb313ef..402699e 100644
--- a/templates/partials/modals.html
+++ b/templates/partials/modals.html
@@ -155,26 +155,33 @@ Name of this image
Add to a MyGiza Collection
-
Hi Heather! (not you? Login to your account .)
+
+
Hi {% if user.full_name %}{{user.full_name}}{% else %}{{user.username}}{% endif %}! (not you? Login to your account .)
-
+
{% include 'partials/close-button.html' with label="Close modal" %}
diff --git a/templates/partials/mygiza-collection-blurb.html b/templates/partials/mygiza-collection-blurb.html
index e12975b..dfdf5ef 100644
--- a/templates/partials/mygiza-collection-blurb.html
+++ b/templates/partials/mygiza-collection-blurb.html
@@ -27,11 +27,15 @@
- {{collection.items|length}} items
+ {{collection.items.all|length}} items
{% for owner in collection.owners.all %}
Created by
- {{owner.full_name}}
+ {% if owner.full_name %}
+ {{owner.full_name}}
+ {% else %}
+ {{owner.username}}
+ {% endif %}
{% endfor %}
diff --git a/tms/templates/tms/full.html b/tms/templates/tms/full.html
index 5e076d6..f9a60dc 100644
--- a/tms/templates/tms/full.html
+++ b/tms/templates/tms/full.html
@@ -842,8 +842,8 @@
windows: [
{ manifestId: url }
]
- });
- }
- });
+ });
+ }
+ });
{% endblock %}
diff --git a/tms/views.py b/tms/views.py
index 1652f6f..546a7a8 100644
--- a/tms/views.py
+++ b/tms/views.py
@@ -3,6 +3,7 @@
from django.template.exceptions import TemplateDoesNotExist
from tms import models
+from giza.forms import CollectionForm
from utils.elastic_backend import ES_INDEX
import json
@@ -22,7 +23,7 @@ def get_type_html_legacy(request, type, id, view):
if view == "intro":
view = "full"
type_object = models.get_item(id, type, ES_INDEX)
- return render(request, 'tms/'+view+'.html', {'object': type_object, 'type': type})
+ return render(request, 'tms/'+view+'.html', {'object': type_object, 'type': type,})
# except:
# raise Http404("There was an error getting this item")
@@ -62,7 +63,11 @@ def get_type_html(request, type, id, view):
if view == "intro":
view = "full"
type_object = models.get_item(id, type, ES_INDEX)
- return render(request, 'pages/'+view+'.html', {'object': type_object, 'type': type})
+
+ # add form for creating a new collection in modal
+ collection_form = CollectionForm()
+
+ return render(request, 'pages/'+view+'.html', {'object': type_object, 'type': type, 'collection_form': collection_form})
# except:
# raise Http404("There was an error getting this item")