Add visibility to ContentBlocks

This commit is contained in:
Pawel Kowalski 2018-09-11 16:15:17 +02:00
parent 35a8184cd1
commit 2c2ad3f8f6
19 changed files with 156 additions and 38 deletions

View File

@ -8,7 +8,7 @@ from api import graphene_wagtail
from book.schema.mutations import BookMutations from book.schema.mutations import BookMutations
from book.schema.queries import BookQuery from filteredbook.schema import BookQuery
from objectives.schema import ObjectivesQuery from objectives.schema import ObjectivesQuery
from rooms.schema import RoomsQuery from rooms.schema import RoomsQuery

View File

@ -1,4 +1,4 @@
# Generated by Django 2.0.6 on 2018-09-04 13:55 # Generated by Django 2.0.6 on 2018-09-11 14:14
from django.db import migrations, models from django.db import migrations, models
import django.db.models.deletion import django.db.models.deletion
@ -43,8 +43,8 @@ class Migration(migrations.Migration):
name='ContentBlock', name='ContentBlock',
fields=[ fields=[
('page_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='wagtailcore.Page')), ('page_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='wagtailcore.Page')),
('contents', wagtail.core.fields.StreamField([('text_block', wagtail.core.blocks.StructBlock([('text', wagtail.core.blocks.RichTextBlock())], icon='doc-full')), ('basic_knowledge', wagtail.core.blocks.StructBlock([('description', wagtail.core.blocks.RichTextBlock()), ('url', wagtail.core.blocks.URLBlock())], icon='placeholder')), ('student_entry', wagtail.core.blocks.StructBlock([('task_text', wagtail.core.blocks.RichTextBlock())], icon='download')), ('image_block', wagtail.images.blocks.ImageChooserBlock(icon='image')), ('task', wagtail.core.blocks.StructBlock([('text', wagtail.core.blocks.RichTextBlock())], icon='tick'))], blank=True, null=True)), ('contents', wagtail.core.fields.StreamField([('text_block', wagtail.core.blocks.StructBlock([('text', wagtail.core.blocks.RichTextBlock())], icon='doc-full')), ('basic_knowledge', wagtail.core.blocks.StructBlock([('description', wagtail.core.blocks.RichTextBlock()), ('url', wagtail.core.blocks.URLBlock())], icon='placeholder')), ('student_entry', wagtail.core.blocks.StructBlock([('task_text', wagtail.core.blocks.RichTextBlock())], icon='download')), ('image_block', wagtail.images.blocks.ImageChooserBlock(icon='image')), ('link_block', wagtail.core.blocks.StructBlock([('text', wagtail.core.blocks.TextBlock()), ('url', wagtail.core.blocks.URLBlock())], icon='link')), ('task', wagtail.core.blocks.StructBlock([('text', wagtail.core.blocks.RichTextBlock())], icon='tick'))], blank=True, null=True)),
('type', models.CharField(choices=[('plain', 'Normal'), ('yellow', 'Gelb'), ('green', 'Grün'), ('blue', 'Blau')], max_length=100)), ('type', models.CharField(choices=[('plain', 'Normal'), ('yellow', 'Gelb'), ('green', 'Grün'), ('blue', 'Blau')], default='plain', max_length=100)),
], ],
options={ options={
'verbose_name': 'Inhaltsblock', 'verbose_name': 'Inhaltsblock',

View File

@ -7,6 +7,7 @@ from wagtail.images.blocks import ImageChooserBlock
from book.blocks import TextBlock, BasicKnowledgeBlock, StudentEntryBlock, LinkBlock from book.blocks import TextBlock, BasicKnowledgeBlock, StudentEntryBlock, LinkBlock
from core.wagtail_utils import StrictHierarchyPage from core.wagtail_utils import StrictHierarchyPage
from user.models import UserGroup
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)

View File

@ -104,27 +104,3 @@ class BookNode(DjangoObjectType):
def resolve_topics(self, *args, **kwargs): def resolve_topics(self, *args, **kwargs):
return Topic.get_by_parent(self) return Topic.get_by_parent(self)
class BookQuery(object):
book = relay.Node.Field(BookNode)
topic = relay.Node.Field(TopicNode)
module = relay.Node.Field(ModuleNode)
chapter = relay.Node.Field(ChapterNode)
books = DjangoFilterConnectionField(BookNode)
topics = DjangoFilterConnectionField(TopicNode)
modules = DjangoFilterConnectionField(ModuleNode)
chapters = DjangoFilterConnectionField(ChapterNode)
def resolve_books(self, *args, **kwargs):
return Book.objects.filter(**kwargs).live()
def resolve_topics(self, *args, **kwargs):
return Topic.objects.filter(**kwargs).live()
def resolve_modules(self, *args, **kwargs):
return Module.objects.filter(**kwargs).live()
def resolve_chapters(self, *args, **kwargs):
return Chapter.objects.filter(**kwargs).live()

View File

@ -49,6 +49,7 @@ INSTALLED_APPS = [
'book', 'book',
'objectives', 'objectives',
'rooms', 'rooms',
'filteredbook',
'wagtail.contrib.forms', 'wagtail.contrib.forms',
'wagtail.contrib.redirects', 'wagtail.contrib.redirects',

View File

View File

@ -0,0 +1,9 @@
from django.contrib import admin
from filteredbook.models import Visibility
@admin.register(Visibility)
class VisibilityAdmin(admin.ModelAdmin):
list_display = ('user_group', 'content_block')
list_filter = ('user_group', 'content_block')

View File

@ -0,0 +1,5 @@
from django.apps import AppConfig
class FilteredbookConfig(AppConfig):
name = 'filteredbook'

View File

@ -0,0 +1,27 @@
# Generated by Django 2.0.6 on 2018-09-11 14:14
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
initial = True
dependencies = [
('book', '0001_initial'),
]
operations = [
migrations.CreateModel(
name='Visibility',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('content_block', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='book.ContentBlock')),
],
options={
'verbose_name': 'Visibility',
'verbose_name_plural': 'Visibilities',
},
),
]

View File

@ -0,0 +1,22 @@
# Generated by Django 2.0.6 on 2018-09-11 14:14
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
initial = True
dependencies = [
('filteredbook', '0001_initial'),
('user', '0001_initial'),
]
operations = [
migrations.AddField(
model_name='visibility',
name='user_group',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='user.UserGroup'),
),
]

View File

@ -0,0 +1,16 @@
from django.db import models
from book.models import ContentBlock
from user.models import UserGroup
class Visibility(models.Model):
class Meta:
verbose_name = 'Visibility'
verbose_name_plural = 'Visibilities'
user_group = models.ForeignKey(UserGroup, blank=False, null=False, on_delete=models.CASCADE)
content_block = models.ForeignKey(ContentBlock, blank=False, null=False, on_delete=models.CASCADE)
def __str__(self):
return 'Visibility {}-{}'.format(self.user_group, self.content_block)

View File

@ -0,0 +1,63 @@
from itertools import chain
import graphene
from django.db.models import Q
from graphene import relay
from graphene_django import DjangoObjectType
from graphene_django.filter import DjangoFilterConnectionField
from book.models import Book, Topic, Module, Chapter, ContentBlock
from book.schema.queries import BookNode, TopicNode, ModuleNode, ContentBlockNode
class FilteredChapterNode(DjangoObjectType):
content_blocks = DjangoFilterConnectionField(ContentBlockNode, user_groups=graphene.List(graphene.String))
class Meta:
model = Chapter
only_fields = [
'slug', 'title',
]
filter_fields = [
'slug', 'title',
]
interfaces = (relay.Node,)
def resolve_content_blocks(self, *args, **kwargs):
user_groups = kwargs.get('user_groups')
if user_groups:
reduced = []
for user_group in user_groups:
content_blocks = ContentBlock.get_by_parent(self).exclude(
Q(visibility__user_group__name=user_group)
)
reduced = chain(reduced, content_blocks)
filtered = list(set(reduced))
return filtered
else:
return ContentBlock.get_by_parent(self)
class BookQuery(object):
book = relay.Node.Field(BookNode)
topic = relay.Node.Field(TopicNode)
module = relay.Node.Field(ModuleNode)
chapter = relay.Node.Field(FilteredChapterNode)
books = DjangoFilterConnectionField(BookNode)
topics = DjangoFilterConnectionField(TopicNode)
modules = DjangoFilterConnectionField(ModuleNode)
chapters = DjangoFilterConnectionField(FilteredChapterNode)
def resolve_books(self, *args, **kwargs):
return Book.objects.filter(**kwargs).live()
def resolve_topics(self, *args, **kwargs):
return Topic.objects.filter(**kwargs).live()
def resolve_modules(self, *args, **kwargs):
return Module.objects.filter(**kwargs).live()
def resolve_chapters(self, *args, **kwargs):
return Chapter.objects.filter(**kwargs).live()

View File

@ -1,4 +1,4 @@
# Generated by Django 2.0.6 on 2018-09-04 13:55 # Generated by Django 2.0.6 on 2018-09-11 14:14
from django.db import migrations, models from django.db import migrations, models
import django.db.models.deletion import django.db.models.deletion

View File

@ -1,4 +1,4 @@
# Generated by Django 2.0.6 on 2018-09-04 13:55 # Generated by Django 2.0.6 on 2018-09-11 14:14
from django.conf import settings from django.conf import settings
from django.db import migrations, models from django.db import migrations, models
@ -10,8 +10,8 @@ class Migration(migrations.Migration):
initial = True initial = True
dependencies = [ dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('book', '0001_initial'), ('book', '0001_initial'),
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('objectives', '0001_initial'), ('objectives', '0001_initial'),
] ]

View File

@ -1,10 +1,9 @@
# Generated by Django 2.0.6 on 2018-09-04 13:55 # Generated by Django 2.0.6 on 2018-09-11 14:14
from django.db import migrations, models from django.db import migrations, models
import django_extensions.db.fields import django_extensions.db.fields
import wagtail.core.blocks import wagtail.core.blocks
import wagtail.core.fields import wagtail.core.fields
import wagtail.images.blocks
class Migration(migrations.Migration): class Migration(migrations.Migration):
@ -37,7 +36,7 @@ class Migration(migrations.Migration):
('description', models.TextField(blank=True, null=True, verbose_name='description')), ('description', models.TextField(blank=True, null=True, verbose_name='description')),
('slug', django_extensions.db.fields.AutoSlugField(blank=True, editable=False, populate_from='title', verbose_name='slug')), ('slug', django_extensions.db.fields.AutoSlugField(blank=True, editable=False, populate_from='title', verbose_name='slug')),
('subtitle', models.CharField(blank=True, max_length=255)), ('subtitle', models.CharField(blank=True, max_length=255)),
('contents', wagtail.core.fields.StreamField([('text_block', wagtail.core.blocks.StructBlock([('text', wagtail.core.blocks.RichTextBlock())], icon='doc-full')), ('image_url', wagtail.core.blocks.StructBlock([('title', wagtail.core.blocks.RichTextBlock()), ('url', wagtail.core.blocks.URLBlock())], icon='image')), ('image_block', wagtail.images.blocks.ImageChooserBlock(icon='image'))], blank=True, null=True)), ('contents', wagtail.core.fields.StreamField([('text_block', wagtail.core.blocks.StructBlock([('text', wagtail.core.blocks.RichTextBlock())], icon='doc-full')), ('image_url', wagtail.core.blocks.StructBlock([('title', wagtail.core.blocks.RichTextBlock()), ('url', wagtail.core.blocks.URLBlock())], icon='image')), ('link_block', wagtail.core.blocks.StructBlock([('text', wagtail.core.blocks.TextBlock()), ('url', wagtail.core.blocks.URLBlock())], icon='link'))], blank=True, null=True)),
], ],
options={ options={
'verbose_name': 'Raumeintrag', 'verbose_name': 'Raumeintrag',

View File

@ -1,4 +1,4 @@
# Generated by Django 2.0.6 on 2018-09-04 13:55 # Generated by Django 2.0.6 on 2018-09-11 14:14
from django.conf import settings from django.conf import settings
from django.db import migrations, models from django.db import migrations, models
@ -10,9 +10,9 @@ class Migration(migrations.Migration):
initial = True initial = True
dependencies = [ dependencies = [
('user', '0001_initial'),
('rooms', '0001_initial'), ('rooms', '0001_initial'),
migrations.swappable_dependency(settings.AUTH_USER_MODEL), migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('user', '0001_initial'),
] ]
operations = [ operations = [

View File

@ -2,7 +2,6 @@ from django.contrib.auth import get_user_model
from django.db import models from django.db import models
from django_extensions.db.models import TitleDescriptionModel, TitleSlugDescriptionModel from django_extensions.db.models import TitleDescriptionModel, TitleSlugDescriptionModel
from wagtail.core.fields import StreamField from wagtail.core.fields import StreamField
from wagtail.images.blocks import ImageChooserBlock
from book.blocks import ImageUrlBlock, LinkBlock from book.blocks import ImageUrlBlock, LinkBlock
from book.models import ContentBlock, TextBlock from book.models import ContentBlock, TextBlock

View File

@ -1,4 +1,4 @@
# Generated by Django 2.0.6 on 2018-09-04 13:55 # Generated by Django 2.0.6 on 2018-09-11 14:14
from django.conf import settings from django.conf import settings
import django.contrib.auth.models import django.contrib.auth.models