From 22c6f598cba9b9455b8b0778d9f1e219def454c4 Mon Sep 17 00:00:00 2001 From: Ian Mayther Date: Fri, 2 Jul 2021 21:13:22 -0700 Subject: [PATCH 01/13] Brought over existing blog files --- .gitignore | 3 ++- blogging/admin.py | 4 ++-- blogging/migrations/0001_initial.py | 2 +- blogging/migrations/0002_category.py | 4 ++-- blogging/models.py | 21 ++++++++++++++++----- blogging/templates/blogging/detail.html | 2 +- blogging/templates/blogging/list.html | 4 ++-- blogging/tests.py | 10 ++-------- blogging/urls.py | 6 ++++-- blogging/views.py | 25 ++++++++++++++++--------- mysite/settings.py | 4 ++-- mysite/templates/base.html | 18 +++++++++--------- mysite/templates/login.html | 2 +- mysite/urls.py | 3 +-- polling/migrations/0001_initial.py | 2 +- polling/models.py | 2 +- polling/templates/polling/detail.html | 4 +--- polling/templates/polling/list.html | 2 +- polling/urls.py | 2 +- polling/views.py | 2 +- 20 files changed, 67 insertions(+), 55 deletions(-) diff --git a/.gitignore b/.gitignore index 6f8f59b..e271278 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ +# created by virtualenv automatically *.pyc *.db -*.sqlite3 +*.sqlite3 \ No newline at end of file diff --git a/blogging/admin.py b/blogging/admin.py index 1175916..3a35761 100644 --- a/blogging/admin.py +++ b/blogging/admin.py @@ -1,6 +1,6 @@ from django.contrib import admin -from blogging.models import Post, Category +from blogging.models import Post, Category admin.site.register(Post) -admin.site.register(Category) +admin.site.register(Category) \ No newline at end of file diff --git a/blogging/migrations/0001_initial.py b/blogging/migrations/0001_initial.py index 5d406bf..90f963a 100644 --- a/blogging/migrations/0001_initial.py +++ b/blogging/migrations/0001_initial.py @@ -1,4 +1,4 @@ -# Generated by Django 2.1.1 on 2019-10-29 01:39 +# Generated by Django 2.1.1 on 2021-06-26 19:07 from django.conf import settings from django.db import migrations, models diff --git a/blogging/migrations/0002_category.py b/blogging/migrations/0002_category.py index 0ccbe19..435d3ab 100644 --- a/blogging/migrations/0002_category.py +++ b/blogging/migrations/0002_category.py @@ -1,4 +1,4 @@ -# Generated by Django 2.1.1 on 2019-11-05 03:35 +# Generated by Django 2.1.1 on 2021-07-01 03:23 from django.db import migrations, models @@ -16,7 +16,7 @@ class Migration(migrations.Migration): ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('name', models.CharField(max_length=128)), ('description', models.TextField(blank=True)), - ('posts', models.ManyToManyField(blank=True, related_name='categories', to='blogging.Post')), + ('posts', models.ManyToManyField(blank=True, related_name='Categories', to='blogging.Post')), ], ), ] diff --git a/blogging/models.py b/blogging/models.py index 10d6cc3..4d9a2ce 100644 --- a/blogging/models.py +++ b/blogging/models.py @@ -1,24 +1,35 @@ +from typing import Set from django.db import models from django.contrib.auth.models import User class Post(models.Model): + #title - CharField max_length = 60 title = models.CharField(max_length=128) + #text - TextField text = models.TextField(blank=True) + #author - CharField max_length = 30 author = models.ForeignKey(User, on_delete=models.CASCADE) + #created_date - DateField auto_now_add=False created_date = models.DateTimeField(auto_now_add=True) + #modified_date - DateField auto_now=True modified_date = models.DateTimeField(auto_now=True) + #published_date - - DateField auto_now_add=True published_date = models.DateTimeField(blank=True, null=True) def __str__(self): return self.title + class Category(models.Model): + #name name = models.CharField(max_length=128) + #description description = models.TextField(blank=True) - posts = models.ManyToManyField(Post, blank=True, related_name='categories') - - class Meta: - verbose_name_plural = 'Categories' - + #posts + posts = models.ManyToManyField(Post, blank=True, related_name='Categories') + def __str__(self): return self.name + + class Meta: + verbose_name_plural = 'Categories' \ No newline at end of file diff --git a/blogging/templates/blogging/detail.html b/blogging/templates/blogging/detail.html index ea5b9c8..cfa7b96 100644 --- a/blogging/templates/blogging/detail.html +++ b/blogging/templates/blogging/detail.html @@ -14,4 +14,4 @@

{{ post }}

  • {{ category }}
  • {% endfor %} -{% endblock %} +{% endblock %} \ No newline at end of file diff --git a/blogging/templates/blogging/list.html b/blogging/templates/blogging/list.html index d8aa919..1cd6a3b 100644 --- a/blogging/templates/blogging/list.html +++ b/blogging/templates/blogging/list.html @@ -4,7 +4,7 @@

    Recent Posts

    {% for post in posts %}

    - {{ post }} + {{ post }}

    {% endfor %} -{% endblock %} +{% endblock %} \ No newline at end of file diff --git a/blogging/tests.py b/blogging/tests.py index 4250226..7fee97d 100644 --- a/blogging/tests.py +++ b/blogging/tests.py @@ -1,15 +1,12 @@ import datetime - from django.test import TestCase from django.contrib.auth.models import User from django.utils.timezone import utc - from blogging.models import Post from blogging.models import Category - class PostTestCase(TestCase): - fixtures = ['blogging_test_fixture.json', ] + fixtures = ['blogging_test_fixture.json',] def setUp(self): self.user = User.objects.get(pk=1) @@ -20,16 +17,13 @@ def test_string_representation(self): actual = str(p1) self.assertEqual(expected, actual) - class CategoryTestCase(TestCase): - def test_string_representation(self): expected = "A Category" c1 = Category(name=expected) actual = str(c1) self.assertEqual(expected, actual) - class FrontEndTestCase(TestCase): """test views provided in the front-end""" fixtures = ['blogging_test_fixture.json', ] @@ -69,4 +63,4 @@ def test_details_only_published(self): self.assertEqual(resp.status_code, 200) self.assertContains(resp, title) else: - self.assertEqual(resp.status_code, 404) + self.assertEqual(resp.status_code, 404) \ No newline at end of file diff --git a/blogging/urls.py b/blogging/urls.py index 172a39c..95a2eb7 100644 --- a/blogging/urls.py +++ b/blogging/urls.py @@ -1,7 +1,9 @@ from django.urls import path -from blogging.views import list_view, detail_view +from blogging.views import stub_view +from blogging.views import list_view +from blogging.views import detail_view urlpatterns = [ path('', list_view, name="blog_index"), path('posts//', detail_view, name="blog_detail"), -] +] \ No newline at end of file diff --git a/blogging/views.py b/blogging/views.py index b4bab4f..e319ac6 100644 --- a/blogging/views.py +++ b/blogging/views.py @@ -1,9 +1,23 @@ from django.shortcuts import render from django.http import HttpResponse, HttpResponseRedirect, Http404 from django.template import loader - from blogging.models import Post +def stub_view(request, *args, **kwargs): + body = "Stub View\n\n" + if args: + body += "Args:\n" + body += "\n".join(["\t%s" % a for a in args]) + if kwargs: + body += "Kwargs:\n" + body += "\n".join(["\t%s: %s" % i for i in kwargs.items()]) + return HttpResponse(body, content_type="text/plain") + +def list_view(request): + published = Post.objects.exclude(published_date__exact=None) + posts = published.order_by('-published_date') + context = {'posts': posts} + return render(request, 'blogging/list.html', context) def detail_view(request, post_id): published = Post.objects.exclude(published_date__exact=None) @@ -12,11 +26,4 @@ def detail_view(request, post_id): except Post.DoesNotExist: raise Http404 context = {'post': post} - return render(request, 'blogging/detail.html', context) - - -def list_view(request): - published = Post.objects.exclude(published_date__exact=None) - posts = published.order_by('-published_date') - context = {'posts': posts} - return render(request, 'blogging/list.html', context) + return render(request, 'blogging/detail.html', context) \ No newline at end of file diff --git a/mysite/settings.py b/mysite/settings.py index 14e4a11..f82c68a 100644 --- a/mysite/settings.py +++ b/mysite/settings.py @@ -20,7 +20,7 @@ # See https://docs.djangoproject.com/en/2.1/howto/deployment/checklist/ # SECURITY WARNING: keep the secret key used in production secret! -SECRET_KEY = 'xak=ca*e6hvh8q5hgfz5l9ees)_pxjif0)ui!ikifg4!enjk+7' +SECRET_KEY = 'pkm=h&_#xt%)@ohx+v8xxd5mw5-2s897p2aea3rj-&nftng4s7' # SECURITY WARNING: don't run with debug turned on in production! DEBUG = True @@ -122,4 +122,4 @@ STATIC_URL = '/static/' LOGIN_URL = '/login/' -LOGIN_REDIRECT_URL = '/' +LOGIN_REDIRECT_URL = '/' \ No newline at end of file diff --git a/mysite/templates/base.html b/mysite/templates/base.html index 4bb0230..8fa58d2 100644 --- a/mysite/templates/base.html +++ b/mysite/templates/base.html @@ -6,16 +6,16 @@ -
    {% block content %} @@ -24,4 +24,4 @@
    - + \ No newline at end of file diff --git a/mysite/templates/login.html b/mysite/templates/login.html index 1566d0f..e1a56ee 100644 --- a/mysite/templates/login.html +++ b/mysite/templates/login.html @@ -6,4 +6,4 @@

    My Blog Login

    {{ form.as_p }}

    -{% endblock %} +{% endblock %} \ No newline at end of file diff --git a/mysite/urls.py b/mysite/urls.py index 446cd8f..7d676e3 100644 --- a/mysite/urls.py +++ b/mysite/urls.py @@ -17,9 +17,8 @@ from django.urls import path, include from django.contrib.auth.views import LoginView, LogoutView - urlpatterns = [ - path('', include('blogging.urls')), + path('', include('blogging.urls')), path('polling/', include('polling.urls')), path('admin/', admin.site.urls), path('login/', LoginView.as_view(template_name='login.html'), name="login"), diff --git a/polling/migrations/0001_initial.py b/polling/migrations/0001_initial.py index 2be60e7..aed7133 100644 --- a/polling/migrations/0001_initial.py +++ b/polling/migrations/0001_initial.py @@ -1,4 +1,4 @@ -# Generated by Django 2.1.1 on 2019-10-29 01:24 +# Generated by Django 2.1.1 on 2021-06-22 12:47 from django.db import migrations, models diff --git a/polling/models.py b/polling/models.py index 6a940d2..d611cbc 100644 --- a/polling/models.py +++ b/polling/models.py @@ -6,4 +6,4 @@ class Poll(models.Model): score = models.IntegerField(default=0) def __str__(self): - return self.title + return self.title \ No newline at end of file diff --git a/polling/templates/polling/detail.html b/polling/templates/polling/detail.html index bb18db0..24ad0dd 100644 --- a/polling/templates/polling/detail.html +++ b/polling/templates/polling/detail.html @@ -1,5 +1,3 @@ -{# polling/templates/polling/detail.html #} - {% extends "base.html" %} {% block content %}

    {{ poll.title }}

    @@ -16,4 +14,4 @@

    {{ poll.title }}

    -{% endblock %} +{% endblock %} \ No newline at end of file diff --git a/polling/templates/polling/list.html b/polling/templates/polling/list.html index 9cf4282..fc90c1a 100644 --- a/polling/templates/polling/list.html +++ b/polling/templates/polling/list.html @@ -8,4 +8,4 @@

    {% endfor %} -{% endblock %} +{% endblock %} \ No newline at end of file diff --git a/polling/urls.py b/polling/urls.py index 9c4e2fd..e51198d 100644 --- a/polling/urls.py +++ b/polling/urls.py @@ -4,4 +4,4 @@ urlpatterns = [ path('', list_view, name="poll_index"), path('polls//', detail_view, name="poll_detail"), -] +] \ No newline at end of file diff --git a/polling/views.py b/polling/views.py index 6339808..4db14de 100644 --- a/polling/views.py +++ b/polling/views.py @@ -20,4 +20,4 @@ def detail_view(request, poll_id): poll.save() context = {'poll': poll} - return render(request, 'polling/detail.html', context) + return render(request, 'polling/detail.html', context) \ No newline at end of file From 20f182478d0b0490ac2f013dcfb92084fbda3965 Mon Sep 17 00:00:00 2001 From: Ian Mayther Date: Fri, 2 Jul 2021 21:58:12 -0700 Subject: [PATCH 02/13] Completed adminModels ? --- blogging/admin.py | 12 +++++++++++- mysite/settings.py | 2 +- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/blogging/admin.py b/blogging/admin.py index 3a35761..a5783aa 100644 --- a/blogging/admin.py +++ b/blogging/admin.py @@ -3,4 +3,14 @@ from blogging.models import Post, Category admin.site.register(Post) -admin.site.register(Category) \ No newline at end of file +admin.site.register(Category) + +class PostAdmin(admin.ModelAdmin): + fields = ( + 'title', 'text', 'author', 'created_date', 'modified_date', 'published_date' + ) + +class Category(admin.ModelAdmin): + fields = ( + 'name', 'description', 'posts' + ) \ No newline at end of file diff --git a/mysite/settings.py b/mysite/settings.py index f82c68a..d429b44 100644 --- a/mysite/settings.py +++ b/mysite/settings.py @@ -20,7 +20,7 @@ # See https://docs.djangoproject.com/en/2.1/howto/deployment/checklist/ # SECURITY WARNING: keep the secret key used in production secret! -SECRET_KEY = 'pkm=h&_#xt%)@ohx+v8xxd5mw5-2s897p2aea3rj-&nftng4s7' +SECRET_KEY = 'xak=ca*e6hvh8q5hgfz5l9ees)_pxjif0)ui!ikifg4!enjk+7' # SECURITY WARNING: don't run with debug turned on in production! DEBUG = True From a3a94890e0c6ea46ca75415c7466507c3aeb92cf Mon Sep 17 00:00:00 2001 From: Ian Mayther Date: Sat, 3 Jul 2021 18:49:50 -0700 Subject: [PATCH 03/13] Finalized category updates in blogging --- blogging/admin.py | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/blogging/admin.py b/blogging/admin.py index a5783aa..5a6258a 100644 --- a/blogging/admin.py +++ b/blogging/admin.py @@ -2,15 +2,19 @@ from blogging.models import Post, Category -admin.site.register(Post) -admin.site.register(Category) +class CategoryAdmin(admin.ModelAdmin): + list_display = ('name', 'description') + + exclude = ('posts',) + +class CategoryInLine(admin.TabularInline): + model = Category.posts.through class PostAdmin(admin.ModelAdmin): - fields = ( - 'title', 'text', 'author', 'created_date', 'modified_date', 'published_date' - ) + inlines = [CategoryInLine,] + + list_display = ('title', 'created_date',) + -class Category(admin.ModelAdmin): - fields = ( - 'name', 'description', 'posts' - ) \ No newline at end of file +admin.site.register(Post, PostAdmin) +admin.site.register(Category, CategoryAdmin) \ No newline at end of file From 347ea0bf6e066fab94c659200a831cd60ae1a0df Mon Sep 17 00:00:00 2001 From: Ian Mayther Date: Mon, 5 Jul 2021 11:22:52 -0700 Subject: [PATCH 04/13] Added serializers and viewsets --- blogging/serializers.py | 13 +++++++++++++ blogging/views.py | 22 +++++++++++++++++++++- 2 files changed, 34 insertions(+), 1 deletion(-) create mode 100644 blogging/serializers.py diff --git a/blogging/serializers.py b/blogging/serializers.py new file mode 100644 index 0000000..5be28fd --- /dev/null +++ b/blogging/serializers.py @@ -0,0 +1,13 @@ +from django.contrib.auth.models import User, Group +from rest_framework import serializers + +class UserSerializer(serializers.HyperlinkedModelSerializer): + class Meta: + model = User + fields = ['url', 'username', 'email', 'groups'] + + +class GroupSerializer(serializers.HyperlinkedModelSerializer): + class Meta: + model = Group + fields = ['url', 'name'] \ No newline at end of file diff --git a/blogging/views.py b/blogging/views.py index e319ac6..1ac5133 100644 --- a/blogging/views.py +++ b/blogging/views.py @@ -2,6 +2,9 @@ from django.http import HttpResponse, HttpResponseRedirect, Http404 from django.template import loader from blogging.models import Post +from rest_framework import viewsets +from rest_framework import permissions +from tutorial.quickstart.serializers import UserSerializer, GroupSerializer def stub_view(request, *args, **kwargs): body = "Stub View\n\n" @@ -26,4 +29,21 @@ def detail_view(request, post_id): except Post.DoesNotExist: raise Http404 context = {'post': post} - return render(request, 'blogging/detail.html', context) \ No newline at end of file + return render(request, 'blogging/detail.html', context) + +class UserViewSet(viewsets.ModelViewSet): + """ + API endpoint that allows users to be viewed or edited. + """ + queryset = User.objects.all().order_by('-date_joined') + serializer_class = UserSerializer + permission_classes = [permissions.IsAuthenticated] + + +class GroupViewSet(viewsets.ModelViewSet): + """ + API endpoint that allows groups to be viewed or edited. + """ + queryset = Group.objects.all() + serializer_class = GroupSerializer + permission_classes = [permissions.IsAuthenticated] \ No newline at end of file From ae995396cb49aeeb49290e02e505774a3bbdb919 Mon Sep 17 00:00:00 2001 From: Ian Mayther Date: Mon, 5 Jul 2021 11:28:29 -0700 Subject: [PATCH 05/13] Updated routers in mysite/urls.py --- mysite/urls.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/mysite/urls.py b/mysite/urls.py index 7d676e3..769d52f 100644 --- a/mysite/urls.py +++ b/mysite/urls.py @@ -16,6 +16,12 @@ from django.contrib import admin from django.urls import path, include from django.contrib.auth.views import LoginView, LogoutView +from rest_framework import routers +from blogging import views + +router = routers.DefaultRouter() +router.register(r'users', views.UserViewSet) +router.register(r'groups', views.GroupViewSet) urlpatterns = [ path('', include('blogging.urls')), @@ -23,4 +29,5 @@ path('admin/', admin.site.urls), path('login/', LoginView.as_view(template_name='login.html'), name="login"), path('logout/', LogoutView.as_view(next_page='/'), name="logout"), + path('api-auth/', include('rest_framework.urls', namespace='rest_framework')), ] From b33e701b73e8c01889a5b21c0c073a36c0a3f204 Mon Sep 17 00:00:00 2001 From: Ian Mayther Date: Mon, 5 Jul 2021 11:30:19 -0700 Subject: [PATCH 06/13] Updated rest_framework to settings.py --- mysite/settings.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/mysite/settings.py b/mysite/settings.py index d429b44..8f30caf 100644 --- a/mysite/settings.py +++ b/mysite/settings.py @@ -39,6 +39,7 @@ 'django.contrib.staticfiles', 'polling', 'blogging', + 'rest_framework', ] MIDDLEWARE = [ @@ -122,4 +123,9 @@ STATIC_URL = '/static/' LOGIN_URL = '/login/' -LOGIN_REDIRECT_URL = '/' \ No newline at end of file +LOGIN_REDIRECT_URL = '/' + +REST_FRAMEWORK = { + 'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination', + 'PAGE_SIZE': 10 +} \ No newline at end of file From 66c12758334a9dd2286d9b593204bc3e1cd55b24 Mon Sep 17 00:00:00 2001 From: Ian Mayther Date: Mon, 5 Jul 2021 11:54:06 -0700 Subject: [PATCH 07/13] Got Users/Groups to work, moving onto Posts/Categories --- blogging/views.py | 5 +++-- mysite/templates/base.html | 2 +- mysite/urls.py | 3 ++- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/blogging/views.py b/blogging/views.py index 1ac5133..3d942d2 100644 --- a/blogging/views.py +++ b/blogging/views.py @@ -1,10 +1,11 @@ from django.shortcuts import render from django.http import HttpResponse, HttpResponseRedirect, Http404 from django.template import loader -from blogging.models import Post +from django.contrib.auth.models import User, Group from rest_framework import viewsets from rest_framework import permissions -from tutorial.quickstart.serializers import UserSerializer, GroupSerializer +from blogging.models import Post +from blogging.serializers import UserSerializer, GroupSerializer def stub_view(request, *args, **kwargs): body = "Stub View\n\n" diff --git a/mysite/templates/base.html b/mysite/templates/base.html index 8fa58d2..8e6acaf 100644 --- a/mysite/templates/base.html +++ b/mysite/templates/base.html @@ -1,4 +1,4 @@ -{% load staticfiles %} +{% load static %} diff --git a/mysite/urls.py b/mysite/urls.py index 769d52f..1ee17aa 100644 --- a/mysite/urls.py +++ b/mysite/urls.py @@ -24,7 +24,8 @@ router.register(r'groups', views.GroupViewSet) urlpatterns = [ - path('', include('blogging.urls')), + path('', include('blogging.urls')), + path('', include(router.urls)), path('polling/', include('polling.urls')), path('admin/', admin.site.urls), path('login/', LoginView.as_view(template_name='login.html'), name="login"), From aabb2b08fab342d24a2a4d5e0e9774db00a7717f Mon Sep 17 00:00:00 2001 From: Ian Mayther Date: Tue, 6 Jul 2021 05:57:11 -0700 Subject: [PATCH 08/13] Added Post viewset, troubleshooting display --- blogging/serializers.py | 10 +++++++++- blogging/views.py | 11 ++++++++++- mysite/urls.py | 1 + 3 files changed, 20 insertions(+), 2 deletions(-) diff --git a/blogging/serializers.py b/blogging/serializers.py index 5be28fd..e4529c7 100644 --- a/blogging/serializers.py +++ b/blogging/serializers.py @@ -1,5 +1,6 @@ from django.contrib.auth.models import User, Group from rest_framework import serializers +from blogging.models import Post, Category class UserSerializer(serializers.HyperlinkedModelSerializer): class Meta: @@ -10,4 +11,11 @@ class Meta: class GroupSerializer(serializers.HyperlinkedModelSerializer): class Meta: model = Group - fields = ['url', 'name'] \ No newline at end of file + fields = ['url', 'name'] + +class PostSerializer(serializers.HyperlinkedModelSerializer): + class Meta: + model = Post + fields = ['url', 'title'] + + #def get_serializer_class(self): diff --git a/blogging/views.py b/blogging/views.py index 3d942d2..0d2f728 100644 --- a/blogging/views.py +++ b/blogging/views.py @@ -2,10 +2,11 @@ from django.http import HttpResponse, HttpResponseRedirect, Http404 from django.template import loader from django.contrib.auth.models import User, Group +from blogging import serializers from rest_framework import viewsets from rest_framework import permissions from blogging.models import Post -from blogging.serializers import UserSerializer, GroupSerializer +from blogging.serializers import PostSerializer, UserSerializer, GroupSerializer def stub_view(request, *args, **kwargs): body = "Stub View\n\n" @@ -47,4 +48,12 @@ class GroupViewSet(viewsets.ModelViewSet): """ queryset = Group.objects.all() serializer_class = GroupSerializer + permission_classes = [permissions.IsAuthenticated] + +class PostViewSet(viewsets.ModelViewSet): + """ + API endpoint that allows Post to be viewed or edited. + """ + queryset = Post.objects.all() + serializers_class = PostSerializer permission_classes = [permissions.IsAuthenticated] \ No newline at end of file diff --git a/mysite/urls.py b/mysite/urls.py index 1ee17aa..c19c5ad 100644 --- a/mysite/urls.py +++ b/mysite/urls.py @@ -22,6 +22,7 @@ router = routers.DefaultRouter() router.register(r'users', views.UserViewSet) router.register(r'groups', views.GroupViewSet) +router.register(r'posts', views.PostViewSet) urlpatterns = [ path('', include('blogging.urls')), From b9488765fa3126280abdf5e96897ae481b476bde Mon Sep 17 00:00:00 2001 From: Ian Mayther Date: Wed, 7 Jul 2021 20:30:34 -0700 Subject: [PATCH 09/13] Completed REST API for posts and categories --- blogging/serializers.py | 10 ++++++++-- blogging/views.py | 14 +++++++++++--- mysite/urls.py | 1 + 3 files changed, 20 insertions(+), 5 deletions(-) diff --git a/blogging/serializers.py b/blogging/serializers.py index e4529c7..ab235d7 100644 --- a/blogging/serializers.py +++ b/blogging/serializers.py @@ -16,6 +16,12 @@ class Meta: class PostSerializer(serializers.HyperlinkedModelSerializer): class Meta: model = Post - fields = ['url', 'title'] + fields = [ + 'url', 'title', 'text', 'author', 'created_date', + 'modified_date','published_date', + ] - #def get_serializer_class(self): +class CategorySerializer(serializers.HyperlinkedModelSerializer): + class Meta: + model = Category + fields = ['url', 'name', 'description', 'posts'] diff --git a/blogging/views.py b/blogging/views.py index 0d2f728..854d247 100644 --- a/blogging/views.py +++ b/blogging/views.py @@ -5,8 +5,8 @@ from blogging import serializers from rest_framework import viewsets from rest_framework import permissions -from blogging.models import Post -from blogging.serializers import PostSerializer, UserSerializer, GroupSerializer +from blogging.models import Category, Post +from blogging.serializers import CategorySerializer, PostSerializer, UserSerializer, GroupSerializer def stub_view(request, *args, **kwargs): body = "Stub View\n\n" @@ -55,5 +55,13 @@ class PostViewSet(viewsets.ModelViewSet): API endpoint that allows Post to be viewed or edited. """ queryset = Post.objects.all() - serializers_class = PostSerializer + serializer_class = PostSerializer + permission_classes = [permissions.IsAuthenticated] + +class CategoryViewSet(viewsets.ModelViewSet): + """ + API endpoint that allows Categories to be viewed or edited. + """ + queryset = Category.objects.all() + serializer_class = CategorySerializer permission_classes = [permissions.IsAuthenticated] \ No newline at end of file diff --git a/mysite/urls.py b/mysite/urls.py index c19c5ad..f1aaac9 100644 --- a/mysite/urls.py +++ b/mysite/urls.py @@ -23,6 +23,7 @@ router.register(r'users', views.UserViewSet) router.register(r'groups', views.GroupViewSet) router.register(r'posts', views.PostViewSet) +router.register(r'categories', views.CategoryViewSet) urlpatterns = [ path('', include('blogging.urls')), From 03da5513e1ca67ce708d7811354b3c49ec8cbd66 Mon Sep 17 00:00:00 2001 From: Ian Mayther Date: Sun, 11 Jul 2021 09:18:15 -0700 Subject: [PATCH 10/13] Failed to figure out reverse and absolute_url --- blogging/views.py | 24 +++++++++++++++++++++++- mysite/urls.py | 1 + 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/blogging/views.py b/blogging/views.py index 854d247..e405ca0 100644 --- a/blogging/views.py +++ b/blogging/views.py @@ -7,6 +7,8 @@ from rest_framework import permissions from blogging.models import Category, Post from blogging.serializers import CategorySerializer, PostSerializer, UserSerializer, GroupSerializer +from django.contrib.syndication.views import Feed +from django.urls import reverse def stub_view(request, *args, **kwargs): body = "Stub View\n\n" @@ -64,4 +66,24 @@ class CategoryViewSet(viewsets.ModelViewSet): """ queryset = Category.objects.all() serializer_class = CategorySerializer - permission_classes = [permissions.IsAuthenticated] \ No newline at end of file + permission_classes = [permissions.IsAuthenticated] + +class LatestEntriesFeed(Feed): + title = 'Most Recent Posts' + link = '/sitenews/' + description = '5 Most Recent Posts to Site' + + def items(self): + return Post.objects.order_by('-published_date')[:5] + + def item_title(self, item): + return item.title + + def item_author(self, item): + return item.author + + def item_id(self, item): + return item.pk + + def item_link(self, item): + return reverse('latest-feed', kwargs= {"id" : self.item_id}) \ No newline at end of file diff --git a/mysite/urls.py b/mysite/urls.py index f1aaac9..d9319f3 100644 --- a/mysite/urls.py +++ b/mysite/urls.py @@ -33,4 +33,5 @@ path('login/', LoginView.as_view(template_name='login.html'), name="login"), path('logout/', LogoutView.as_view(next_page='/'), name="logout"), path('api-auth/', include('rest_framework.urls', namespace='rest_framework')), + path('latest/feed/', views.LatestEntriesFeed(), name= 'latest-feed') ] From 18b7a044679f8ca8cc3aafaa8e004af4843abdf6 Mon Sep 17 00:00:00 2001 From: Ian Mayther Date: Sun, 11 Jul 2021 09:58:24 -0700 Subject: [PATCH 11/13] Finished FB login --- mysite/settings.py | 14 +++++++++++++- mysite/urls.py | 3 ++- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/mysite/settings.py b/mysite/settings.py index 8f30caf..3ec4c8c 100644 --- a/mysite/settings.py +++ b/mysite/settings.py @@ -37,6 +37,11 @@ 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', + 'django.contrib.sites', + 'allauth', + 'allauth.account', + 'allauth.socialaccount', + 'allauth.socialaccount.providers.facebook', 'polling', 'blogging', 'rest_framework', @@ -128,4 +133,11 @@ REST_FRAMEWORK = { 'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination', 'PAGE_SIZE': 10 -} \ No newline at end of file +} + +AUTHENTICATION_BACKENDS = [ + 'django.contrib.auth.backends.ModelBackend', + 'allauth.account.auth_backends.AuthenticationBackend', +] + +SITE_ID = 1 diff --git a/mysite/urls.py b/mysite/urls.py index d9319f3..b62c63d 100644 --- a/mysite/urls.py +++ b/mysite/urls.py @@ -33,5 +33,6 @@ path('login/', LoginView.as_view(template_name='login.html'), name="login"), path('logout/', LogoutView.as_view(next_page='/'), name="logout"), path('api-auth/', include('rest_framework.urls', namespace='rest_framework')), - path('latest/feed/', views.LatestEntriesFeed(), name= 'latest-feed') + path('latest/feed/', views.LatestEntriesFeed(), name= 'latest-feed'), + path('accounts/', include('allauth.urls')), ] From 6e8299154833d3c76b5c44d4618ec7e0e5257ad9 Mon Sep 17 00:00:00 2001 From: Ian Mayther Date: Sun, 11 Jul 2021 10:01:50 -0700 Subject: [PATCH 12/13] Added feeds from failed attempts to RSS --- blogging/feeds.py | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 blogging/feeds.py diff --git a/blogging/feeds.py b/blogging/feeds.py new file mode 100644 index 0000000..d88b5b8 --- /dev/null +++ b/blogging/feeds.py @@ -0,0 +1,20 @@ +from django.contrib.syndication.views import Feed +from django.urls import reverse +from blogging.models import Post + +class LatestEntriesFeed(Feed): + title = 'Most Recent Posts' + link = '/sitenews/' + description = '5 Most Recent Posts to Site' + + def items(self): + return Post.objects.order_by('-published_date')[:5] + + def item_title(self, item): + return item.title + + def item_author(self, item): + return item.author + + def item_link(self, item): + return reverse('post', args=[item.pk]) From 6e26e7d2f697aa8de9feac277d5da1bf0209fded Mon Sep 17 00:00:00 2001 From: Ian Mayther Date: Wed, 14 Jul 2021 15:51:41 -0700 Subject: [PATCH 13/13] Added production.py file and updated requirements --- mysite/production.py | 16 ++++++++++++++++ requirements.txt | 24 ++++++++++++++++++++++-- 2 files changed, 38 insertions(+), 2 deletions(-) create mode 100644 mysite/production.py diff --git a/mysite/production.py b/mysite/production.py new file mode 100644 index 0000000..ef4250c --- /dev/null +++ b/mysite/production.py @@ -0,0 +1,16 @@ +import os + +import dj_database_url + +from .settings import * + + +DATABASES = { + 'default': dj_database_url.config(default='sqlite:///' + os.path.join(BASE_DIR, 'db.sqlite3')) + } + +DEBUG = False +TEMPLATE_DEBUG = False +ALLOWED_HOSTS = [os.environ.get('ALLOWED_HOSTS'), 'localhost'] +STATIC_ROOT = os.path.join(BASE_DIR, 'static') +SECRET_KEY = os.environ.get('SECRET_KEY') \ No newline at end of file diff --git a/requirements.txt b/requirements.txt index 81580ab..312aa54 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,2 +1,22 @@ -Django==2.1.1 -pytz==2019.3 +asgiref==3.4.1 +certifi==2021.5.30 +cffi==1.14.6 +chardet==4.0.0 +cryptography==3.4.7 +defusedxml==0.7.1 +dj-database-url==0.5.0 +Django==3.2.5 +django-allauth==0.45.0 +djangorestframework==3.12.4 +idna==2.10 +oauthlib==3.1.1 +psycopg2==2.9.1 +pycparser==2.20 +PyJWT==2.1.0 +python3-openid==3.2.0 +pytz==2021.1 +requests==2.25.1 +requests-oauthlib==1.3.0 +sqlparse==0.4.1 +typing-extensions==3.10.0.0 +urllib3==1.26.6