aboutsummaryrefslogtreecommitdiff
path: root/apps
diff options
context:
space:
mode:
authorluxagraf <sng@luxagraf.net>2018-11-24 22:29:02 -0600
committerluxagraf <sng@luxagraf.net>2018-11-24 22:29:02 -0600
commit0c2a092e8d8ad33a1c306ee9efca0da96eb56415 (patch)
tree0aaf48f20771c97ec30e005ef818ef6ce4856097 /apps
parent7a284139f6b97bb06548e69d47eef188bc99099d (diff)
way to much for a single commit
Diffstat (limited to 'apps')
-rw-r--r--apps/accounts/migrations/0001_initial.py2
-rw-r--r--apps/accounts/models.py2
-rw-r--r--apps/notes/admin.py6
-rw-r--r--apps/notes/forms.py4
-rw-r--r--apps/notes/migrations/0001_initial.py57
-rw-r--r--apps/notes/migrations/0002_auto_20181111_1825.py31
-rw-r--r--apps/notes/migrations/0003_note_folder.py19
-rw-r--r--apps/notes/migrations/0004_auto_20181117_2039.py27
-rw-r--r--apps/notes/migrations/0005_auto_20181119_1145.py28
-rw-r--r--apps/notes/models.py59
-rw-r--r--apps/notes/serializers.py10
-rw-r--r--apps/notes/tests/test_models.py24
-rw-r--r--apps/notes/tests/test_views.py32
-rw-r--r--apps/notes/urls.py20
-rw-r--r--apps/notes/views.py68
-rw-r--r--apps/utils/util.py23
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