From 32e141b79e0aa9ff04ed9d25375820c3fce600e2 Mon Sep 17 00:00:00 2001 From: JeroenSweerts Date: Thu, 31 Oct 2019 17:56:49 +0100 Subject: [PATCH 1/5] All steps of lesson7 completed --- {myblog => blogging}/__init__.py | 0 blogging/admin.py | 8 + blogging/apps.py | 5 + .../migrations/0001_initial.py | 2 +- .../migrations/0002_category.py | 6 +- {myblog => blogging}/migrations/__init__.py | 0 {myblog => blogging}/models.py | 5 +- {myblog => blogging}/static/django_blog.css | 148 +++++++++--------- .../templates/blogging}/detail.html | 0 .../templates/blogging}/list.html | 0 {myblog => blogging}/tests.py | 17 +- blogging/urls.py | 9 ++ blogging/views.py | 43 +++++ main.py | 20 +++ myblog/admin.py | 6 - myblog/apps.py | 5 - myblog/fixtures/myblog_test_fixture.json | 38 ----- myblog/migrations/0003_auto_20181018_1130.py | 17 -- myblog/urls.py | 7 - myblog/views.py | 30 ---- mysite/settings.py | 6 +- mysite/templates/base.html | 18 ++- mysite/urls.py | 7 +- polling/__init__.py | 0 polling/admin.py | 5 + polling/apps.py | 5 + polling/migrations/0001_initial.py | 23 +++ polling/migrations/__init__.py | 0 polling/models.py | 10 ++ polling/templates/polling/detail.html | 19 +++ polling/templates/polling/list.html | 13 ++ polling/tests.py | 3 + polling/urls.py | 9 ++ polling/views.py | 25 +++ requirements.txt | 2 - 35 files changed, 300 insertions(+), 211 deletions(-) rename {myblog => blogging}/__init__.py (100%) create mode 100644 blogging/admin.py create mode 100644 blogging/apps.py rename {myblog => blogging}/migrations/0001_initial.py (95%) rename {myblog => blogging}/migrations/0002_category.py (80%) rename {myblog => blogging}/migrations/__init__.py (100%) rename {myblog => blogging}/models.py (87%) rename {myblog => blogging}/static/django_blog.css (94%) rename {myblog/templates => blogging/templates/blogging}/detail.html (100%) rename {myblog/templates => blogging/templates/blogging}/list.html (100%) rename {myblog => blogging}/tests.py (91%) create mode 100644 blogging/urls.py create mode 100644 blogging/views.py create mode 100644 main.py delete mode 100644 myblog/admin.py delete mode 100644 myblog/apps.py delete mode 100644 myblog/fixtures/myblog_test_fixture.json delete mode 100644 myblog/migrations/0003_auto_20181018_1130.py delete mode 100644 myblog/urls.py delete mode 100644 myblog/views.py create mode 100644 polling/__init__.py create mode 100644 polling/admin.py create mode 100644 polling/apps.py create mode 100644 polling/migrations/0001_initial.py create mode 100644 polling/migrations/__init__.py create mode 100644 polling/models.py create mode 100644 polling/templates/polling/detail.html create mode 100644 polling/templates/polling/list.html create mode 100644 polling/tests.py create mode 100644 polling/urls.py create mode 100644 polling/views.py delete mode 100644 requirements.txt diff --git a/myblog/__init__.py b/blogging/__init__.py similarity index 100% rename from myblog/__init__.py rename to blogging/__init__.py diff --git a/blogging/admin.py b/blogging/admin.py new file mode 100644 index 0000000..a3a9dc3 --- /dev/null +++ b/blogging/admin.py @@ -0,0 +1,8 @@ +from django.contrib import admin + +from blogging.models import Post, Category + +# and a new admin registration +admin.site.register(Post) +admin.site.register(Category) +# Register your models here. diff --git a/blogging/apps.py b/blogging/apps.py new file mode 100644 index 0000000..01164e0 --- /dev/null +++ b/blogging/apps.py @@ -0,0 +1,5 @@ +from django.apps import AppConfig + + +class BloggingConfig(AppConfig): + name = 'blogging' diff --git a/myblog/migrations/0001_initial.py b/blogging/migrations/0001_initial.py similarity index 95% rename from myblog/migrations/0001_initial.py rename to blogging/migrations/0001_initial.py index 140c165..c86c160 100644 --- a/myblog/migrations/0001_initial.py +++ b/blogging/migrations/0001_initial.py @@ -1,4 +1,4 @@ -# Generated by Django 2.1.1 on 2018-10-14 18:36 +# Generated by Django 2.1.1 on 2019-10-30 16:31 from django.conf import settings from django.db import migrations, models diff --git a/myblog/migrations/0002_category.py b/blogging/migrations/0002_category.py similarity index 80% rename from myblog/migrations/0002_category.py rename to blogging/migrations/0002_category.py index 14cd2cb..70aebc5 100644 --- a/myblog/migrations/0002_category.py +++ b/blogging/migrations/0002_category.py @@ -1,4 +1,4 @@ -# Generated by Django 2.1.1 on 2018-10-18 18:24 +# Generated by Django 2.1.1 on 2019-10-31 12:22 from django.db import migrations, models @@ -6,7 +6,7 @@ class Migration(migrations.Migration): dependencies = [ - ('myblog', '0001_initial'), + ('blogging', '0001_initial'), ] operations = [ @@ -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='myblog.Post')), + ('posts', models.ManyToManyField(blank=True, related_name='categories', to='blogging.Post')), ], ), ] diff --git a/myblog/migrations/__init__.py b/blogging/migrations/__init__.py similarity index 100% rename from myblog/migrations/__init__.py rename to blogging/migrations/__init__.py diff --git a/myblog/models.py b/blogging/models.py similarity index 87% rename from myblog/models.py rename to blogging/models.py index 74b3229..c67c0a2 100644 --- a/myblog/models.py +++ b/blogging/models.py @@ -1,4 +1,4 @@ -from django.db import models +from django.db import models # <-- This is already in the file from django.contrib.auth.models import User class Post(models.Model): @@ -18,8 +18,7 @@ class Category(models.Model): posts = models.ManyToManyField(Post, blank=True, related_name='categories') class Meta: - verbose_name_plural = 'Categories' + verbose_name_plural = 'Categories' def __str__(self): return self.name - diff --git a/myblog/static/django_blog.css b/blogging/static/django_blog.css similarity index 94% rename from myblog/static/django_blog.css rename to blogging/static/django_blog.css index 45a882d..69012d6 100644 --- a/myblog/static/django_blog.css +++ b/blogging/static/django_blog.css @@ -1,74 +1,74 @@ -body { - background-color: #eee; - color: #111; - font-family: "HelveticaNeue-Light", "Helvetica Neue Light", "Helvetica Neue", Helvetica, Arial, "Lucida Grande", sans-serif; - margin:0; - padding:0; -} -#container { - margin:0; - padding:0; - margin-top: 0px; -} -#header { - background-color: #333; - border-botton: 1px solid #111; - margin:0; - padding:0; -} -#control-bar { - margin: 0em 0em 1em; - list-style: none; - list-style-type: none; - text-align: right; - color: #eee; - font-size: 80%; - padding-bottom: 0.4em; -} -#control-bar li { - display: inline-block; -} -#control-bar li a { - color: #eee; - padding: 0.5em; - text-decoration: none; -} -#control-bar li a:hover { - color: #cce; -} -#content { - margin: 0em 1em 1em; -} - -ul#entries { - list-style: none; - list-style-type: none; -} -div.entry { - margin-right: 2em; - margin-top: 1em; - border-top: 1px solid #cecece; -} -ul#entries li:first-child div.entry { - border-top: none; - margin-top: 0em; -} -div.entry-body { - margin-left: 2em; -} -.notification { - float: right; - text-align: center; - width: 25%; - padding: 1em; -} -.info { - background-color: #aae; -} -ul.categories { - list-style: none; - list-style-type: none; -} -ul.categories li { - display: inline; -} +body { + background-color: #eee; + color: #111; + font-family: "HelveticaNeue-Light", "Helvetica Neue Light", "Helvetica Neue", Helvetica, Arial, "Lucida Grande", sans-serif; + margin:0; + padding:0; +} +#container { + margin:0; + padding:0; + margin-top: 0px; +} +#header { + background-color: #333; + border-botton: 1px solid #111; + margin:0; + padding:0; +} +#control-bar { + margin: 0em 0em 1em; + list-style: none; + list-style-type: none; + text-align: right; + color: #eee; + font-size: 80%; + padding-bottom: 0.4em; +} +#control-bar li { + display: inline-block; +} +#control-bar li a { + color: #eee; + padding: 0.5em; + text-decoration: none; +} +#control-bar li a:hover { + color: #cce; +} +#content { + margin: 0em 1em 1em; +} + +ul#entries { + list-style: none; + list-style-type: none; +} +div.entry { + margin-right: 2em; + margin-top: 1em; + border-top: 1px solid #cecece; +} +ul#entries li:first-child div.entry { + border-top: none; + margin-top: 0em; +} +div.entry-body { + margin-left: 2em; +} +.notification { + float: right; + text-align: center; + width: 25%; + padding: 1em; +} +.info { + background-color: #aae; +} +ul.categories { + list-style: none; + list-style-type: none; +} +ul.categories li { + display: inline; +} diff --git a/myblog/templates/detail.html b/blogging/templates/blogging/detail.html similarity index 100% rename from myblog/templates/detail.html rename to blogging/templates/blogging/detail.html diff --git a/myblog/templates/list.html b/blogging/templates/blogging/list.html similarity index 100% rename from myblog/templates/list.html rename to blogging/templates/blogging/list.html diff --git a/myblog/tests.py b/blogging/tests.py similarity index 91% rename from myblog/tests.py rename to blogging/tests.py index f487500..b55f821 100644 --- a/myblog/tests.py +++ b/blogging/tests.py @@ -1,28 +1,24 @@ -import datetime - from django.test import TestCase -from django.utils.timezone import utc from django.contrib.auth.models import User +from blogging.models import Post # add this import at the top +from blogging.models import Category -from myblog.models import Post, Category - +import datetime +from django.utils.timezone import utc class PostTestCase(TestCase): - fixtures = ['myblog_test_fixture.json', ] + fixtures = ['blogging_test_fixture.json', ] def setUp(self): self.user = User.objects.get(pk=1) - def test_string_representation(self): expected = "This is a title" p1 = Post(title=expected) actual = str(p1) self.assertEqual(expected, actual) - class CategoryTestCase(TestCase): - def test_string_representation(self): expected = "A Category" c1 = Category(name=expected) @@ -32,7 +28,7 @@ def test_string_representation(self): class FrontEndTestCase(TestCase): """test views provided in the front-end""" - fixtures = ['myblog_test_fixture.json', ] + fixtures = ['blogging_test_fixture.json', ] def setUp(self): self.now = datetime.datetime.utcnow().replace(tzinfo=utc) @@ -60,7 +56,6 @@ def test_list_only_published(self): else: self.assertNotContains(resp, title) - def test_details_only_published(self): for count in range(1, 11): title = "Post %d Title" % count diff --git a/blogging/urls.py b/blogging/urls.py new file mode 100644 index 0000000..d0318bc --- /dev/null +++ b/blogging/urls.py @@ -0,0 +1,9 @@ +from django.urls import path +# from blogging.views import stub_view +from blogging.views import list_view, detail_view + +urlpatterns = [ + # path('', stub_view, name="blog_index"), + path('',list_view, name="blog_index"), + path('posts//', detail_view, name="blog_detail"), +] diff --git a/blogging/views.py b/blogging/views.py new file mode 100644 index 0000000..62bc1e7 --- /dev/null +++ b/blogging/views.py @@ -0,0 +1,43 @@ +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') +# template = loader.get_template('blogging/list.html') +# context = {'posts': posts} +# body = template.render(context) +# return HttpResponse(body, content_type="text/html") + +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) + try: + post = published.get(pk=post_id) + except Post.DoesNotExist: + raise Http404 + context = {'post': post} + return render(request, 'blogging/detail.html', context) + +# Create your views here. diff --git a/main.py b/main.py new file mode 100644 index 0000000..f2f1db2 --- /dev/null +++ b/main.py @@ -0,0 +1,20 @@ +import sys +import json + +import requests + +# Use Like python githubber.py JASchilz +# (or another user name) + +if __name__ == "__main__": + username = sys.argv[1] + + # TODO: + # + # 1. Retrieve a list of "events" associated with the given user name + # 2. Print out the time stamp associated with the first event in that list. + + print("COMPLETE THE TODOs") + + + diff --git a/myblog/admin.py b/myblog/admin.py deleted file mode 100644 index dc0ebd0..0000000 --- a/myblog/admin.py +++ /dev/null @@ -1,6 +0,0 @@ -from django.contrib import admin -from myblog.models import Post, Category - -admin.site.register(Post) -admin.site.register(Category) - diff --git a/myblog/apps.py b/myblog/apps.py deleted file mode 100644 index 5e29c8d..0000000 --- a/myblog/apps.py +++ /dev/null @@ -1,5 +0,0 @@ -from django.apps import AppConfig - - -class MyblogConfig(AppConfig): - name = 'myblog' diff --git a/myblog/fixtures/myblog_test_fixture.json b/myblog/fixtures/myblog_test_fixture.json deleted file mode 100644 index bf5269e..0000000 --- a/myblog/fixtures/myblog_test_fixture.json +++ /dev/null @@ -1,38 +0,0 @@ -[ - { - "pk": 1, - "model": "auth.user", - "fields": { - "username": "admin", - "first_name": "Mr.", - "last_name": "Administrator", - "is_active": true, - "is_superuser": true, - "is_staff": true, - "last_login": "2013-05-24T05:35:58.628Z", - "groups": [], - "user_permissions": [], - "password": "pbkdf2_sha256$10000$1rQazFNdOfFt$6aw/uIrv2uASkZ7moXMTajSN+ySYuowBnbP6ILNQntE=", - "email": "admin@example.com", - "date_joined": "2013-05-24T05:35:58.628Z" - } - }, - { - "pk": 2, - "model": "auth.user", - "fields": { - "username": "noname", - "first_name": "", - "last_name": "", - "is_active": true, - "is_superuser": true, - "is_staff": true, - "last_login": "2013-05-24T05:35:58.628Z", - "groups": [], - "user_permissions": [], - "password": "pbkdf2_sha256$10000$1rQazFNdOfFt$6aw/uIrv2uASkZ7moXMTajSN+ySYuowBnbP6ILNQntE=", - "email": "noname@example.com", - "date_joined": "2013-05-24T05:35:58.628Z" - } - } -] diff --git a/myblog/migrations/0003_auto_20181018_1130.py b/myblog/migrations/0003_auto_20181018_1130.py deleted file mode 100644 index f000eb9..0000000 --- a/myblog/migrations/0003_auto_20181018_1130.py +++ /dev/null @@ -1,17 +0,0 @@ -# Generated by Django 2.1.1 on 2018-10-18 18:30 - -from django.db import migrations - - -class Migration(migrations.Migration): - - dependencies = [ - ('myblog', '0002_category'), - ] - - operations = [ - migrations.AlterModelOptions( - name='category', - options={'verbose_name_plural': 'Categories'}, - ), - ] diff --git a/myblog/urls.py b/myblog/urls.py deleted file mode 100644 index e54f3a5..0000000 --- a/myblog/urls.py +++ /dev/null @@ -1,7 +0,0 @@ -from django.urls import path -from .views import list_view, detail_view - -urlpatterns = [ - path('', list_view, name="blog_index"), - path('posts//', detail_view, name="blog_detail"), -] diff --git a/myblog/views.py b/myblog/views.py deleted file mode 100644 index 0de484c..0000000 --- a/myblog/views.py +++ /dev/null @@ -1,30 +0,0 @@ -from django.shortcuts import render -from django.http import HttpResponse, HttpResponseRedirect, Http404 -from django.template import loader -from myblog.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, 'list.html', context) - -def detail_view(request, post_id): - published = Post.objects.exclude(published_date__exact=None) - try: - post = published.get(pk=post_id) - except Post.DoesNotExist: - raise Http404 - context = {'post': post} - return render(request, 'detail.html', context) diff --git a/mysite/settings.py b/mysite/settings.py index 7a2226d..573caec 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 = 'y0(#ucw(w$u0)9324ch^^wyce%h$wgwf2r2_zrb6c0_=cyfy8^' +SECRET_KEY = 'vb*@9ob8w+284ur($2!&x28=3^6ootx&ib#jmqn5=c=s__5fk%' # SECURITY WARNING: don't run with debug turned on in production! DEBUG = True @@ -37,7 +37,8 @@ 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', - 'myblog', + 'polling', + 'blogging', ] MIDDLEWARE = [ @@ -119,6 +120,5 @@ # https://docs.djangoproject.com/en/2.1/howto/static-files/ STATIC_URL = '/static/' - LOGIN_URL = '/login/' LOGIN_REDIRECT_URL = '/' diff --git a/mysite/templates/base.html b/mysite/templates/base.html index ba6ae50..5fc02a2 100644 --- a/mysite/templates/base.html +++ b/mysite/templates/base.html @@ -1,4 +1,6 @@ {% load staticfiles %} +{# mysite/templates/base.html #} + @@ -7,15 +9,15 @@ {# header ends here #} +
  • logout
  • + {% else %} +
  • login
  • + {% endif %} + +
    {% block content %} diff --git a/mysite/urls.py b/mysite/urls.py index 059aaad..ee02385 100644 --- a/mysite/urls.py +++ b/mysite/urls.py @@ -14,12 +14,13 @@ 2. Add a URL to urlpatterns: path('blog/', include('blog.urls')) """ from django.contrib import admin -from django.urls import path, include -from django.contrib.auth.views import LoginView, LogoutView +from django.urls import path, include # <-- Make sure you have both of these imports. +from django.contrib.auth.views import LoginView, LogoutView urlpatterns = [ + path('polling/', include('polling.urls')), # <-- Add this path('admin/', admin.site.urls), - path('', include('myblog.urls')), + path('', include('blogging.urls')), path('login/', LoginView.as_view(template_name='login.html'), name="login"), path('logout/', LogoutView.as_view(next_page='/'), name="logout"), ] diff --git a/polling/__init__.py b/polling/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/polling/admin.py b/polling/admin.py new file mode 100644 index 0000000..1874dd8 --- /dev/null +++ b/polling/admin.py @@ -0,0 +1,5 @@ +# blogging/admin.py +from django.contrib import admin +from polling.models import Poll + +admin.site.register(Poll) diff --git a/polling/apps.py b/polling/apps.py new file mode 100644 index 0000000..6254e54 --- /dev/null +++ b/polling/apps.py @@ -0,0 +1,5 @@ +from django.apps import AppConfig + + +class PollingConfig(AppConfig): + name = 'polling' diff --git a/polling/migrations/0001_initial.py b/polling/migrations/0001_initial.py new file mode 100644 index 0000000..97114cb --- /dev/null +++ b/polling/migrations/0001_initial.py @@ -0,0 +1,23 @@ +# Generated by Django 2.1.1 on 2019-10-29 14:59 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + ] + + operations = [ + migrations.CreateModel( + name='Poll', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('title', models.CharField(max_length=128)), + ('text', models.TextField(blank=True)), + ('score', models.IntegerField(default=0)), + ], + ), + ] diff --git a/polling/migrations/__init__.py b/polling/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/polling/models.py b/polling/models.py new file mode 100644 index 0000000..fa8da99 --- /dev/null +++ b/polling/models.py @@ -0,0 +1,10 @@ +# blogging/models.py +from django.db import models + +class Poll(models.Model): + title = models.CharField(max_length=128) + text = models.TextField(blank=True) + score = models.IntegerField(default=0) + + def __str__(self): + return self.title diff --git a/polling/templates/polling/detail.html b/polling/templates/polling/detail.html new file mode 100644 index 0000000..bb18db0 --- /dev/null +++ b/polling/templates/polling/detail.html @@ -0,0 +1,19 @@ +{# polling/templates/polling/detail.html #} + +{% extends "base.html" %} +{% block content %} +

    {{ poll.title }}

    +
    + {{ poll.text }} +
    +
    + Current score: {{ poll.score }} +
    +
    +
    + {% csrf_token %} + + +
    +
    +{% endblock %} diff --git a/polling/templates/polling/list.html b/polling/templates/polling/list.html new file mode 100644 index 0000000..fc36de4 --- /dev/null +++ b/polling/templates/polling/list.html @@ -0,0 +1,13 @@ +{# polling/templates/polling/list.html #} + +{% extends "base.html" %} +{% block content %} +

    Polls

    +{% for poll in polls %} + +{% endfor %} +{% endblock %} diff --git a/polling/tests.py b/polling/tests.py new file mode 100644 index 0000000..7ce503c --- /dev/null +++ b/polling/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/polling/urls.py b/polling/urls.py new file mode 100644 index 0000000..e3560bc --- /dev/null +++ b/polling/urls.py @@ -0,0 +1,9 @@ +# polling/urls.py + +from django.urls import path +from polling.views import list_view, detail_view + +urlpatterns = [ + path('', list_view, name="poll_index"), + path('polls//', detail_view, name="poll_detail"), +] diff --git a/polling/views.py b/polling/views.py new file mode 100644 index 0000000..439dc7a --- /dev/null +++ b/polling/views.py @@ -0,0 +1,25 @@ +# polling/views.py + +from django.shortcuts import render +from django.http import Http404 +from polling.models import Poll + +def list_view(request): + context = {'polls': Poll.objects.all()} + return render(request, 'polling/list.html', context) + +def detail_view(request, poll_id): + try: + poll = Poll.objects.get(pk=poll_id) + except Poll.DoesNotExist: + raise Http404 + + if request.method == "POST": + if request.POST.get("vote") == "Yes": + poll.score += 1 + else: + poll.score -= 1 + poll.save() + + context = {'poll': poll} + return render(request, 'polling/detail.html', context) diff --git a/requirements.txt b/requirements.txt deleted file mode 100644 index ef52540..0000000 --- a/requirements.txt +++ /dev/null @@ -1,2 +0,0 @@ -Django==2.1.1 -pytz==2018.5 From 8ae3432eb071e97e3cd0150100d592e62e299cf7 Mon Sep 17 00:00:00 2001 From: JeroenSweerts Date: Thu, 31 Oct 2019 19:20:50 +0100 Subject: [PATCH 2/5] added ModelAdmin class --- blogging/admin.py | 20 +++++++++-- .../migrations/0003_auto_20191031_1814.py | 34 +++++++++++++++++++ blogging/models.py | 4 +++ 3 files changed, 55 insertions(+), 3 deletions(-) create mode 100644 blogging/migrations/0003_auto_20191031_1814.py diff --git a/blogging/admin.py b/blogging/admin.py index a3a9dc3..f0958fd 100644 --- a/blogging/admin.py +++ b/blogging/admin.py @@ -1,8 +1,22 @@ from django.contrib import admin -from blogging.models import Post, Category +from blogging.models import Post, Category, ModelAdmin2 + + +class ModelAdminClass(admin.TabularInline): + model = ModelAdmin2 + extra = 1 + + +class PostAdmin(admin.ModelAdmin): + inlines = (ModelAdminClass,) + + +class CategoryAdmin(admin.ModelAdmin): + exclude = ('posts',) + # and a new admin registration -admin.site.register(Post) -admin.site.register(Category) +admin.site.register(Post, PostAdmin) +admin.site.register(Category, CategoryAdmin) # Register your models here. diff --git a/blogging/migrations/0003_auto_20191031_1814.py b/blogging/migrations/0003_auto_20191031_1814.py new file mode 100644 index 0000000..1f1e2de --- /dev/null +++ b/blogging/migrations/0003_auto_20191031_1814.py @@ -0,0 +1,34 @@ +# Generated by Django 2.1.1 on 2019-10-31 18:14 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('blogging', '0002_category'), + ] + + operations = [ + migrations.CreateModel( + name='ModelAdmin2', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ], + ), + migrations.AlterModelOptions( + name='category', + options={'verbose_name_plural': 'Categories'}, + ), + migrations.AddField( + model_name='modeladmin2', + name='category', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='blogging.Category'), + ), + migrations.AddField( + model_name='modeladmin2', + name='post', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='blogging.Post'), + ), + ] diff --git a/blogging/models.py b/blogging/models.py index c67c0a2..578bc16 100644 --- a/blogging/models.py +++ b/blogging/models.py @@ -22,3 +22,7 @@ class Meta: def __str__(self): return self.name + +class ModelAdmin2(models.Model): + post = models.ForeignKey(Post, on_delete=models.CASCADE) + category = models.ForeignKey(Category, on_delete=models.CASCADE) From 55d93e9d714fd2bfe3ee9ca46e41404755180af7 Mon Sep 17 00:00:00 2001 From: JeroenSweerts Date: Sat, 2 Nov 2019 13:52:23 +0100 Subject: [PATCH 3/5] added Facebook login --- mysite/settings.py | 24 ++++++++++++++++++++++++ mysite/templates/login.html | 9 +++++++++ mysite/urls.py | 2 ++ 3 files changed, 35 insertions(+) diff --git a/mysite/settings.py b/mysite/settings.py index 573caec..9f2c5eb 100644 --- a/mysite/settings.py +++ b/mysite/settings.py @@ -39,6 +39,13 @@ 'django.contrib.staticfiles', 'polling', 'blogging', + + 'django.contrib.sites', + + 'allauth', + 'allauth.account', + 'allauth.socialaccount', + 'allauth.socialaccount.providers.facebook', ] MIDDLEWARE = [ @@ -69,6 +76,9 @@ }, ] + + + WSGI_APPLICATION = 'mysite.wsgi.application' @@ -122,3 +132,17 @@ STATIC_URL = '/static/' LOGIN_URL = '/login/' LOGIN_REDIRECT_URL = '/' + + +AUTHENTICATION_BACKENDS = ( + # Needed to login by username in Django admin, regardless of `allauth` + 'django.contrib.auth.backends.ModelBackend', + + # `allauth` specific authentication methods, such as login by e-mail + 'allauth.account.auth_backends.AuthenticationBackend', +) + +SITE_ID = 1 + +LOGIN_REDIRECT_URL = '/' + diff --git a/mysite/templates/login.html b/mysite/templates/login.html index 1566d0f..757105c 100644 --- a/mysite/templates/login.html +++ b/mysite/templates/login.html @@ -1,9 +1,18 @@ {% extends "base.html" %} +{% load socialaccount %} +{% providers_media_js %} + + + {% block content %}

    My Blog Login

    {% csrf_token %} {{ form.as_p }}

    + + + + {% endblock %} diff --git a/mysite/urls.py b/mysite/urls.py index ee02385..220d22e 100644 --- a/mysite/urls.py +++ b/mysite/urls.py @@ -15,6 +15,7 @@ """ from django.contrib import admin from django.urls import path, include # <-- Make sure you have both of these imports. +from django.conf.urls import url from django.contrib.auth.views import LoginView, LogoutView urlpatterns = [ @@ -23,4 +24,5 @@ path('', include('blogging.urls')), path('login/', LoginView.as_view(template_name='login.html'), name="login"), path('logout/', LogoutView.as_view(next_page='/'), name="logout"), + url(r'^accounts/', include('allauth.urls')), ] From b657f5b859659330a6ec17f4a27f4449b67fe4f0 Mon Sep 17 00:00:00 2001 From: JeroenSweerts Date: Sun, 3 Nov 2019 02:49:13 +0100 Subject: [PATCH 4/5] Added a form and button to enter new blog --- blogging/forms.py | 7 +++++++ blogging/models.py | 5 +++++ blogging/templates/blogging/post_edit.html | 10 ++++++++++ blogging/urls.py | 3 ++- blogging/views.py | 18 +++++++++++++++++- mysite/templates/base.html | 1 + mysite/urls.py | 5 ++++- 7 files changed, 46 insertions(+), 3 deletions(-) create mode 100644 blogging/forms.py create mode 100644 blogging/templates/blogging/post_edit.html diff --git a/blogging/forms.py b/blogging/forms.py new file mode 100644 index 0000000..c39d07e --- /dev/null +++ b/blogging/forms.py @@ -0,0 +1,7 @@ +from django.forms import ModelForm +from blogging.models import Post + +class PostForm(ModelForm): + class Meta: + model = Post + fields = ['title', 'text'] diff --git a/blogging/models.py b/blogging/models.py index 578bc16..58d805f 100644 --- a/blogging/models.py +++ b/blogging/models.py @@ -1,5 +1,7 @@ from django.db import models # <-- This is already in the file from django.contrib.auth.models import User +from django.urls import reverse + class Post(models.Model): title = models.CharField(max_length=128) @@ -9,6 +11,9 @@ class Post(models.Model): modified_date = models.DateTimeField(auto_now=True) published_date = models.DateTimeField(blank=True, null=True) + def get_absolute_url(self): + return reverse('blogging:detail', kwargs={'pk':self.pk}) + def __str__(self): return self.title diff --git a/blogging/templates/blogging/post_edit.html b/blogging/templates/blogging/post_edit.html new file mode 100644 index 0000000..480c539 --- /dev/null +++ b/blogging/templates/blogging/post_edit.html @@ -0,0 +1,10 @@ +{% extends 'base.html' %} + +{% block content %} +Home +

    New post

    +
    {% csrf_token %} + {{ form.as_p }} + +
    +{% endblock %} diff --git a/blogging/urls.py b/blogging/urls.py index d0318bc..e6e7262 100644 --- a/blogging/urls.py +++ b/blogging/urls.py @@ -1,9 +1,10 @@ from django.urls import path # from blogging.views import stub_view -from blogging.views import list_view, detail_view +from blogging.views import list_view, detail_view,post_new urlpatterns = [ # path('', stub_view, name="blog_index"), path('',list_view, name="blog_index"), path('posts//', detail_view, name="blog_detail"), + path('',post_new,name='post-add') ] diff --git a/blogging/views.py b/blogging/views.py index 62bc1e7..cb8c7d5 100644 --- a/blogging/views.py +++ b/blogging/views.py @@ -1,4 +1,7 @@ -from django.shortcuts import render +from django.shortcuts import render, redirect +from django import forms +from django.utils import timezone +from blogging.forms import PostForm from django.http import HttpResponse, HttpResponseRedirect, Http404 @@ -41,3 +44,16 @@ def detail_view(request, post_id): return render(request, 'blogging/detail.html', context) # Create your views here. +def post_new(request): + if request.method == "POST": + form = PostForm(request.POST) + if form.is_valid(): + post = form.save(commit=False) + post.author = request.user + post.published_date = timezone.now() + post.save() + + return redirect('/') + else: + form = PostForm() + return render(request, "blogging/post_edit.html", {'form': form}) diff --git a/mysite/templates/base.html b/mysite/templates/base.html index 5fc02a2..8a58e44 100644 --- a/mysite/templates/base.html +++ b/mysite/templates/base.html @@ -10,6 +10,7 @@