diff options
author | luxagraf <sng@luxagraf.net> | 2018-11-24 22:29:02 -0600 |
---|---|---|
committer | luxagraf <sng@luxagraf.net> | 2018-11-24 22:29:02 -0600 |
commit | 0c2a092e8d8ad33a1c306ee9efca0da96eb56415 (patch) | |
tree | 0aaf48f20771c97ec30e005ef818ef6ce4856097 /apps | |
parent | 7a284139f6b97bb06548e69d47eef188bc99099d (diff) |
way to much for a single commit
Diffstat (limited to 'apps')
-rw-r--r-- | apps/accounts/migrations/0001_initial.py | 2 | ||||
-rw-r--r-- | apps/accounts/models.py | 2 | ||||
-rw-r--r-- | apps/notes/admin.py | 6 | ||||
-rw-r--r-- | apps/notes/forms.py | 4 | ||||
-rw-r--r-- | apps/notes/migrations/0001_initial.py | 57 | ||||
-rw-r--r-- | apps/notes/migrations/0002_auto_20181111_1825.py | 31 | ||||
-rw-r--r-- | apps/notes/migrations/0003_note_folder.py | 19 | ||||
-rw-r--r-- | apps/notes/migrations/0004_auto_20181117_2039.py | 27 | ||||
-rw-r--r-- | apps/notes/migrations/0005_auto_20181119_1145.py | 28 | ||||
-rw-r--r-- | apps/notes/models.py | 59 | ||||
-rw-r--r-- | apps/notes/serializers.py | 10 | ||||
-rw-r--r-- | apps/notes/tests/test_models.py | 24 | ||||
-rw-r--r-- | apps/notes/tests/test_views.py | 32 | ||||
-rw-r--r-- | apps/notes/urls.py | 20 | ||||
-rw-r--r-- | apps/notes/views.py | 68 | ||||
-rw-r--r-- | apps/utils/util.py | 23 |
16 files changed, 218 insertions, 194 deletions
diff --git a/apps/accounts/migrations/0001_initial.py b/apps/accounts/migrations/0001_initial.py index 0e2775e..36aa6ba 100644 --- a/apps/accounts/migrations/0001_initial.py +++ b/apps/accounts/migrations/0001_initial.py @@ -1,4 +1,4 @@ -# Generated by Django 2.1.2 on 2018-11-02 19:01 +# Generated by Django 2.1.2 on 2018-11-24 04:41 from django.conf import settings import django.contrib.auth.models diff --git a/apps/accounts/models.py b/apps/accounts/models.py index a930081..5ed7634 100644 --- a/apps/accounts/models.py +++ b/apps/accounts/models.py @@ -15,6 +15,8 @@ class UserProfile(models.Model): website = models.CharField(max_length=300, null=True, blank=True, default='') location = models.CharField(max_length=300, null=True, blank=True, default='') bio = models.TextField(null=True, blank=True, default='') + #default_note_public = models.BooleanField(default=False) + #default_note_folder = models.ForeignKey('notes.Folder', null=True, on_delete=models.SET_NULL) def __str__(self): return self.user.username diff --git a/apps/notes/admin.py b/apps/notes/admin.py index dbac05c..3958d55 100644 --- a/apps/notes/admin.py +++ b/apps/notes/admin.py @@ -1,6 +1,6 @@ from django.contrib import admin -from .models import Note, Folder +from .models import Note, Notebook @admin.register(Note) @@ -8,6 +8,6 @@ class NoteAdmin(admin.ModelAdmin): pass -@admin.register(Folder) -class FolderAdmin(admin.ModelAdmin): +@admin.register(Notebook) +class NotebookAdmin(admin.ModelAdmin): pass diff --git a/apps/notes/forms.py b/apps/notes/forms.py index 6a27ec9..a7a4f8d 100644 --- a/apps/notes/forms.py +++ b/apps/notes/forms.py @@ -7,9 +7,9 @@ from .models import Note class NoteForm(forms.ModelForm): class Meta: model = Note - fields = ['title', 'body_markdown', 'url', 'tags'] + fields = ['title', 'body_text', 'body_html', 'body_qjson', 'notebook', 'url', 'tags'] labels = { - "body_markdown": _("Note"), + "body": _("Note"), } def __init__(self, *args, **kwargs): diff --git a/apps/notes/migrations/0001_initial.py b/apps/notes/migrations/0001_initial.py index 3f04eb7..f8e2fff 100644 --- a/apps/notes/migrations/0001_initial.py +++ b/apps/notes/migrations/0001_initial.py @@ -1,9 +1,11 @@ -# Generated by Django 2.1.2 on 2018-11-11 18:01 +# Generated by Django 2.1.2 on 2018-11-24 13:55 from django.conf import settings +import django.contrib.postgres.fields.jsonb from django.db import migrations, models import django.db.models.deletion import taggit.managers +import uuid class Migration(migrations.Migration): @@ -11,28 +13,61 @@ class Migration(migrations.Migration): initial = True dependencies = [ - migrations.swappable_dependency(settings.AUTH_USER_MODEL), ('taggit', '0002_auto_20150616_2121'), + migrations.swappable_dependency(settings.AUTH_USER_MODEL), ] operations = [ migrations.CreateModel( - name='Folder', + name='Note', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('name', models.CharField(max_length=250)), - ('created_by', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), + ('unique_id', models.UUIDField(default=uuid.uuid4, editable=False)), + ('date_created', models.DateTimeField(auto_now_add=True)), + ('date_updated', models.DateTimeField(auto_now=True)), + ('title', models.CharField(max_length=250)), + ('body_text', models.TextField(null=True)), + ('body_html', models.TextField(blank=True, null=True)), + ('body_qjson', django.contrib.postgres.fields.jsonb.JSONField(blank=True, null=True)), + ('url', models.CharField(blank=True, max_length=250, null=True)), + ('slug', models.SlugField(blank=True)), + ('is_public', models.BooleanField(default=False)), ], ), migrations.CreateModel( - name='Note', + name='Notebook', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('title', models.CharField(max_length=250)), - ('body_markdown', models.TextField(null=True)), - ('url', models.CharField(max_length=250)), - ('created_by', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), - ('tags', taggit.managers.TaggableManager(blank=True, help_text='Tags', through='taggit.TaggedItem', to='taggit.Tag', verbose_name='Tags')), + ('unique_id', models.UUIDField(default=uuid.uuid4, editable=False)), + ('name', models.CharField(max_length=250)), + ('url', models.CharField(blank=True, max_length=250, null=True)), + ('slug', models.SlugField(blank=True)), + ('date_created', models.DateTimeField(auto_now_add=True)), + ('date_updated', models.DateTimeField(auto_now=True)), + ('owner', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), ], ), + migrations.AddField( + model_name='note', + name='notebook', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='notes.Notebook'), + ), + migrations.AddField( + model_name='note', + name='owner', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL), + ), + migrations.AddField( + model_name='note', + name='tags', + field=taggit.managers.TaggableManager(blank=True, help_text='Tags', through='taggit.TaggedItem', to='taggit.Tag', verbose_name='Tags'), + ), + migrations.AlterUniqueTogether( + name='notebook', + unique_together={('owner', 'slug')}, + ), + migrations.AlterUniqueTogether( + name='note', + unique_together={('owner', 'slug')}, + ), ] diff --git a/apps/notes/migrations/0002_auto_20181111_1825.py b/apps/notes/migrations/0002_auto_20181111_1825.py deleted file mode 100644 index a7bc1c7..0000000 --- a/apps/notes/migrations/0002_auto_20181111_1825.py +++ /dev/null @@ -1,31 +0,0 @@ -# Generated by Django 2.1.2 on 2018-11-11 18:25 - -import datetime -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('notes', '0001_initial'), - ] - - operations = [ - migrations.AddField( - model_name='note', - name='date_created', - field=models.DateTimeField(blank=True, default=datetime.datetime(2018, 11, 11, 18, 25, 29, 645561), editable=False), - preserve_default=False, - ), - migrations.AddField( - model_name='note', - name='date_updated', - field=models.DateTimeField(blank=True, default=datetime.datetime(2018, 11, 11, 18, 25, 42, 867666), editable=False), - preserve_default=False, - ), - migrations.AddField( - model_name='note', - name='slug', - field=models.SlugField(blank=True, unique=True), - ), - ] diff --git a/apps/notes/migrations/0003_note_folder.py b/apps/notes/migrations/0003_note_folder.py deleted file mode 100644 index d548429..0000000 --- a/apps/notes/migrations/0003_note_folder.py +++ /dev/null @@ -1,19 +0,0 @@ -# Generated by Django 2.1.2 on 2018-11-14 15:41 - -from django.db import migrations, models -import django.db.models.deletion - - -class Migration(migrations.Migration): - - dependencies = [ - ('notes', '0002_auto_20181111_1825'), - ] - - operations = [ - migrations.AddField( - model_name='note', - name='folder', - field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to='notes.Folder'), - ), - ] diff --git a/apps/notes/migrations/0004_auto_20181117_2039.py b/apps/notes/migrations/0004_auto_20181117_2039.py deleted file mode 100644 index 6fc6f2d..0000000 --- a/apps/notes/migrations/0004_auto_20181117_2039.py +++ /dev/null @@ -1,27 +0,0 @@ -# Generated by Django 2.1.2 on 2018-11-18 02:39 - -import datetime -from django.db import migrations, models -from django.utils.timezone import utc - - -class Migration(migrations.Migration): - - dependencies = [ - ('notes', '0003_note_folder'), - ] - - operations = [ - migrations.AddField( - model_name='folder', - name='date_created', - field=models.DateTimeField(blank=True, default=datetime.datetime(2018, 11, 18, 2, 38, 45, 996162, tzinfo=utc), editable=False), - preserve_default=False, - ), - migrations.AddField( - model_name='folder', - name='date_updated', - field=models.DateTimeField(blank=True, default=datetime.datetime(2018, 11, 18, 2, 39, 0, 850658, tzinfo=utc), editable=False), - preserve_default=False, - ), - ] diff --git a/apps/notes/migrations/0005_auto_20181119_1145.py b/apps/notes/migrations/0005_auto_20181119_1145.py deleted file mode 100644 index 9b6cee7..0000000 --- a/apps/notes/migrations/0005_auto_20181119_1145.py +++ /dev/null @@ -1,28 +0,0 @@ -# Generated by Django 2.1.2 on 2018-11-19 17:45 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('notes', '0004_auto_20181117_2039'), - ] - - operations = [ - migrations.RenameField( - model_name='note', - old_name='body_markdown', - new_name='body', - ), - migrations.AddField( - model_name='note', - name='is_public', - field=models.BooleanField(default=False), - ), - migrations.AddField( - model_name='note', - name='rendered_body', - field=models.TextField(null=True), - ), - ] diff --git a/apps/notes/models.py b/apps/notes/models.py index 318b079..83766a9 100644 --- a/apps/notes/models.py +++ b/apps/notes/models.py @@ -1,48 +1,67 @@ +import uuid from django.db import models from django.utils import timezone +from django.utils.functional import cached_property from django.template.defaultfilters import slugify from django.urls import reverse +from django.contrib.postgres.fields import JSONField from taggit.managers import TaggableManager from django.conf import settings +from utils.util import unique_slug_generator -class Folder(models.Model): - created_by = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE) + +class Notebook(models.Model): + unique_id = models.UUIDField(default=uuid.uuid4, editable=False) + owner = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE) name = models.CharField(max_length=250) - date_created = models.DateTimeField(blank=True, editable=False) - date_updated = models.DateTimeField(blank=True, editable=False) + url = models.CharField(max_length=250, null=True, blank=True) + slug = models.SlugField(blank=True) + date_created = models.DateTimeField(blank=True, auto_now_add=True, editable=False) + date_updated = models.DateTimeField(blank=True, auto_now=True, editable=False) + + class Meta: + unique_together = ("owner", "slug") def __str__(self): return self.name + def save(self, **kwargs): + if self._state.adding: + self.slug = unique_slug_generator(self) + super(Notebook, self).save() + class Note(models.Model): - created_by = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE) - date_created = models.DateTimeField(blank=True, editable=False) - date_updated = models.DateTimeField(blank=True, editable=False) + unique_id = models.UUIDField(default=uuid.uuid4, editable=False) + owner = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE) + date_created = models.DateTimeField(blank=True, auto_now_add=True, editable=False) + date_updated = models.DateTimeField(blank=True, auto_now=True, editable=False) title = models.CharField(max_length=250) - body = models.TextField(null=True) - rendered_body = models.TextField(null=True) - url = models.CharField(max_length=250) - slug = models.SlugField(unique=True, blank=True) - folder = models.ForeignKey(Folder, null=True, on_delete=models.SET_NULL) + body_text = models.TextField(null=True) + body_html = models.TextField(null=True, blank=True) + body_qjson = JSONField(null=True, blank=True) + url = models.CharField(max_length=250, null=True, blank=True) + slug = models.SlugField(blank=True) + notebook = models.ForeignKey(Notebook, null=True, blank=True, on_delete=models.SET_NULL) tags = TaggableManager(blank=True, help_text='Tags') is_public = models.BooleanField(default=False) + class Meta: + unique_together = ("owner", "slug") + def __str__(self): return self.title + @cached_property def get_absolute_url(self): - return reverse("notes:notes-detail", kwargs={"pk": self.pk}) + return reverse("notes:note-detail", kwargs={"user": self.owner.username, "slug": self.slug}) def save(self, **kwargs): - # On save, update timestamps (users updated through admin.py) - if not self.id: - self.date_created = timezone.now() - self.slug = slugify(self.title)[:50] - if not self.title: - self.title = str(self.date_created) - self.date_updated = timezone.now() + if not self.title: + self.title = str(self.body_text)[:50] + if self._state.adding: + self.slug = unique_slug_generator(self) super(Note, self).save() diff --git a/apps/notes/serializers.py b/apps/notes/serializers.py index 0929e79..2fbcc1f 100644 --- a/apps/notes/serializers.py +++ b/apps/notes/serializers.py @@ -1,18 +1,18 @@ from rest_framework import serializers from taggit_serializer.serializers import TagListSerializerField, TaggitSerializer -from .models import Note, Folder +from .models import Note, Notebook -class NoteSerializer(TaggitSerializer, serializers.HyperlinkedModelSerializer): +class NoteSerializer(TaggitSerializer, serializers.ModelSerializer): tags = TagListSerializerField() class Meta: model = Note - fields = ('title', 'body', 'url', 'tags') + fields = ('title', 'body_text', 'body_qjson', 'body_html', 'url', 'notebook', 'tags') -class FolderSerializer(serializers.HyperlinkedModelSerializer): +class NotebookSerializer(serializers.HyperlinkedModelSerializer): class Meta: - model = Folder + model = Notebook fields = ('name',) diff --git a/apps/notes/tests/test_models.py b/apps/notes/tests/test_models.py index ddb731e..cf21aca 100644 --- a/apps/notes/tests/test_models.py +++ b/apps/notes/tests/test_models.py @@ -1,32 +1,32 @@ from django.test import TestCase from mixer.backend.django import mixer -from notes.models import Note, Folder +from notes.models import Note, Notebook from accounts.models import User -class FolderModelTest(TestCase): +class NotebookModelTest(TestCase): def test_string_representation(self): user = mixer.blend(User, username='tpynchon') - folder = Folder(created_by=user, name="My Folder") - self.assertEqual(str(folder), "My Folder") + notebook = Notebook(owner=user, name="San Miguel Notes") + self.assertEqual(str(notebook), "San Miguel Notes") class NoteModelTest(TestCase): def setUp(self): - self.user = mixer.blend(User, username='test') + self.user = mixer.blend(User, username='tpynchon') self.note = Note.objects.create( - created_by=self.user, + owner=self.user, title="test note", - body="the body of the note", + body_text="the body of the note", url="https://luxagraf.net/", tags="mine,cool site" ) self.note.save() self.note_no_title = Note.objects.create( - created_by=self.user, - body="the body of the note", + owner=self.user, + body_text="the body of the note", url="https://luxagraf.net/", tags="mine,cool site" ) @@ -34,11 +34,11 @@ class NoteModelTest(TestCase): def test_string_representation(self): self.assertEqual(str(self.note), "test note") - self.assertEqual(str(self.note.body), "the body of the note") + self.assertEqual(str(self.note.body_text), "the body of the note") self.assertEqual(str(self.note.url), "https://luxagraf.net/") self.assertEqual(str(self.note.tags), "mine,cool site") # titleless note gets date - self.assertEqual(str(self.note_no_title), str(self.note_no_title.date_created)) + self.assertEqual(str(self.note_no_title), str(self.note_no_title.body_text)[:50]) def test_get_absolute_url(self): - self.assertEqual(str(self.note.get_absolute_url()), "/notes/%s/" % (self.note.id)) + self.assertEqual(str(self.note.get_absolute_url), "/notes/%s/%s" % (self.note.owner.username, self.note.slug)) diff --git a/apps/notes/tests/test_views.py b/apps/notes/tests/test_views.py index 05cb8db..4f9a4ce 100644 --- a/apps/notes/tests/test_views.py +++ b/apps/notes/tests/test_views.py @@ -2,6 +2,7 @@ import json from django.test import Client from django.test import RequestFactory, TestCase from django.urls import reverse +from django.template.defaultfilters import slugify from rest_framework.test import force_authenticate from rest_framework.test import APIRequestFactory @@ -25,9 +26,9 @@ class NotesViewsTest(TestCase): self.user = User.objects.create(username='testuser', password='password') self.bad_user = User.objects.create(username='someoneelse', password='password') self.note = Note.objects.create( - created_by=self.user, + owner=self.user, title="test note", - body="the body of the note", + body_text="the body of the note", url="https://luxagraf.net/", ) self.note.tags.add("mine,cool site") @@ -40,6 +41,19 @@ class NotesViewsTest(TestCase): self.assertEqual(response.status_code, 200) # bad_user + def test_note_create_view(self): + data = { + 'title': "test note post", + 'body_text': "the body of the note", + 'url': "https://luxagraf.net/", + 'tags': [], + } + self.client.force_login(self.user) + url = reverse("notes:note-create") + response = self.client.post(url, data) + self.assertEqual(response.status_code, 302) + self.assertRedirects(response, '/notes/%s/%s' % (self.user.username, slugify(data['title']))) + def test_api_list(self): # Make an authenticated request to the view... request = self.factory.get('/api/notes/') @@ -51,36 +65,36 @@ class NotesViewsTest(TestCase): self.assertEqual(api_data['title'], 'test note') self.assertEqual(api_data['tags'], ['mine,cool site']) - def test_note_create(self): + def test_api_note_create(self): ''' - post some data to create a new note + Post some data to create a new note ''' data = { 'title': "test note post", - 'body': "the body of the note", + 'body_text': "the body of the note", 'url': "https://luxagraf.net/", 'tags': [], } self.apiclient.force_authenticate(self.user) - url = reverse("notes:notes-list") + url = reverse("notes-api-list") response = self.apiclient.post(url, data, format='json') self.assertEqual(response.status_code, 201) self.assertEqual(Note.objects.count(), 2) response.render() api_data = json.loads(response.content.decode('utf8')) self.assertEqual(api_data['title'], 'test note post') - self.assertEqual(api_data['body'], 'the body of the note') + self.assertEqual(api_data['body_text'], 'the body of the note') self.assertEqual(api_data['tags'], []) def test_note_create_bad(self): # create another user data = { 'title': "", - 'body': "the body of the note", + 'body_text': "the body of the note", 'url': "https://luxagraf.net/", 'tags': [], } - url = reverse("notes:notes-list") + url = reverse("notes-api-list") self.apiclient.force_authenticate(self.user) response = self.apiclient.post(url, data, format='json') self.assertEqual(response.status_code, 400) diff --git a/apps/notes/urls.py b/apps/notes/urls.py index cbb1884..ccfcc9e 100644 --- a/apps/notes/urls.py +++ b/apps/notes/urls.py @@ -1,17 +1,17 @@ from django.urls import path -from django.conf.urls import include -from rest_framework import routers - -from .views import NoteViewSet, FolderViewSet, NoteListView - -router = routers.DefaultRouter() -router.register(r'notes/folder', FolderViewSet, basename="folder") -router.register(r'notes', NoteViewSet, basename="notes") +from .views import ( + NoteDetailView, + NoteCreateView, + NoteListView, + NoteListRedirectView, +) app_name = "notes" urlpatterns = [ - path(r'', NoteListView.as_view(), name='homepage',), - path(r'', include(router.urls)), + path(r'create/', NoteCreateView.as_view(), name='note-create',), + path(r'<str:user>/<slug>', NoteDetailView.as_view(), name='note-detail',), + path(r'<str:user>/', NoteListView.as_view(), name='note-list',), + path(r'', NoteListRedirectView.as_view(), name='note-redirect',), ] diff --git a/apps/notes/views.py b/apps/notes/views.py index e4b8fda..b971390 100644 --- a/apps/notes/views.py +++ b/apps/notes/views.py @@ -1,21 +1,23 @@ from django.views.generic import CreateView, ListView, UpdateView, DeleteView from django.views.generic.detail import DetailView +from django.views.generic.base import View, RedirectView from django.utils.decorators import method_decorator from django.contrib.auth.decorators import login_required from django.shortcuts import get_object_or_404, render, redirect -from django.urls import reverse +from django.urls import reverse, reverse_lazy from rest_framework import viewsets from rest_framework.response import Response from rest_framework.decorators import list_route from rest_framework import permissions -from .serializers import NoteSerializer, FolderSerializer -from .models import Note, Folder +from .serializers import NoteSerializer, NotebookSerializer +from .models import Note, Notebook +from .forms import NoteForm @method_decorator(login_required, name='dispatch') -class LoggedInCreateViewWithUser(CreateView): +class LoggedInViewWithUser(View): def get_form_kwargs(self, **kwargs): kwargs = super().get_form_kwargs(**kwargs) @@ -23,20 +25,56 @@ class LoggedInCreateViewWithUser(CreateView): return kwargs -class NoteListView(ListView): +class NoteListView(LoggedInViewWithUser, ListView): model = Note def get_queryset(self): if not self.request.user.is_anonymous: - return Note.objects.filter(created_by=self.request.user) + return Note.objects.filter(owner=self.request.user) def get_template_names(self): + # print("IP Address for debug-toolbar: " + self.request.META['REMOTE_ADDR']) if not self.request.user.is_anonymous: return ['notes/notes_list.html'] else: return ['sell.html'] +class NoteListRedirectView(RedirectView, LoggedInViewWithUser): + + def get_redirect_url(self, *args, **kwargs): + return reverse_lazy("notes:note-list", kwargs={"user": self.request.user.username}) + + +class NoteDetailView(UpdateView, LoggedInViewWithUser): + model = Note + form_class = NoteForm + template_name = 'notes/notes_detail.html' + + def get_queryset(self): + if not self.request.user.is_anonymous: + return Note.objects.filter(owner=self.request.user) + + def get_context_data(self, **kwargs): + context = super().get_context_data(**kwargs) + context['notes_list'] = Note.objects.filter(owner=self.request.user) + return context + + +class NoteCreateView(CreateView, LoggedInViewWithUser): + model = Note + form_class = NoteForm + template_name = 'notes/notes_create.html' + + def form_valid(self, form): + form.instance.owner = self.request.user + self.object = form.save() + return super(NoteCreateView, self).form_valid(form) + + def get_success_url(self): + return reverse_lazy('notes:note-detail', kwargs={'user': self.request.user.username, 'slug': self.object.slug}) + + class IsOwnerOrDeny(permissions.BasePermission): """ Custom permission to only allow owners to post to their endpoint @@ -52,15 +90,13 @@ class NoteViewSet(viewsets.ModelViewSet): API endpoint that allows notes to be viewed or edited. """ serializer_class = NoteSerializer - permission_classes = (permissions.IsAuthenticated, IsOwnerOrDeny,) + permission_classes = (permissions.IsAuthenticated,) def get_queryset(self): - return Note.objects.filter(created_by=self.request.user).order_by('-date_created') + return Note.objects.filter(owner=self.request.user).order_by('-date_created') - @list_route(methods=['post']) def perform_create(self, serializer): - serializer.save(created_by=self.request.user) - return super(NoteViewSet, self).perform_create(serializer) + serializer.save(owner=self.request.user) def get_object(self): obj = get_object_or_404(self.get_queryset(), pk=self.kwargs["pk"]) @@ -71,14 +107,14 @@ class NoteViewSet(viewsets.ModelViewSet): return obj -class FolderViewSet(viewsets.ModelViewSet): +class NotebookViewSet(viewsets.ModelViewSet): """ - API endpoint that allows folder to be viewed or edited. + API endpoint that allows botebook to be viewed or edited. """ - serializer_class = FolderSerializer + serializer_class = NotebookSerializer def get_queryset(self): - return Folder.objects.filter(created_by=self.request.user).order_by('-date_created') + return Notebook.objects.filter(owner=self.request.user).order_by('-date_created') def perform_create(self, serializer): - serializer.save(created_by=self.request.user) + serializer.save(owner=self.request.user) diff --git a/apps/utils/util.py b/apps/utils/util.py index 0c089ee..899b73f 100644 --- a/apps/utils/util.py +++ b/apps/utils/util.py @@ -1,5 +1,8 @@ import re +import random +import string from django.apps import apps +from django.utils.text import slugify from django.template.loader import render_to_string from bs4 import BeautifulSoup import markdown @@ -82,3 +85,23 @@ def parse_video(s): if soup.find('video'): return True return False + + +def random_string_generator(size=10, chars=string.ascii_lowercase + string.digits): + return ''.join(random.choice(chars) for _ in range(size)) + + +def unique_slug_generator(instance, new_slug=None): + if new_slug is not None: + slug = new_slug + else: + slug = slugify(instance.title) + Klass = instance.__class__ + qs_exists = Klass.objects.filter(slug=slug).exists() + if qs_exists: + new_slug = "{slug}-{randstr}".format( + slug=slug, + randstr=random_string_generator(size=4) + ) + return unique_slug_generator(instance, new_slug=new_slug) + return slug |