├── .gitignore ├── blog ├── __init__.py ├── admin.py ├── apps.py ├── forms.py ├── migrations │ ├── 0001_initial.py │ ├── 0002_comment.py │ ├── 0003_comment_approved.py │ └── __init__.py ├── models.py ├── static │ └── css │ │ ├── blog.css │ │ └── zenburn.css ├── templates │ ├── blog │ │ ├── add_comment_to_post.html │ │ ├── base.html │ │ ├── post_detail.html │ │ ├── post_draft_list.html │ │ ├── post_edit.html │ │ ├── post_list.html │ │ └── signup.html │ └── registration │ │ └── login.html ├── templatetags │ ├── __init__.py │ └── markdownify.py ├── tests.py ├── urls.py └── views.py ├── db.sqlite3 ├── manage.py ├── mysite ├── __init__.py ├── __pycache__ │ ├── __init__.cpython-36.pyc │ └── settings.cpython-36.pyc ├── settings.py ├── urls.py └── wsgi.py └── requirements.txt /.gitignore: -------------------------------------------------------------------------------- 1 | .idea* 2 | *.pyc 3 | *.DS_Store -------------------------------------------------------------------------------- /blog/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CleverProgrammer/my_django_site/e05a27b92015031a5edf383918981fb038ab9195/blog/__init__.py -------------------------------------------------------------------------------- /blog/admin.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | from .models import Post, Comment 3 | 4 | # Register your models here. 5 | admin.site.register(Post) 6 | admin.site.register(Comment) 7 | -------------------------------------------------------------------------------- /blog/apps.py: -------------------------------------------------------------------------------- 1 | from django.apps import AppConfig 2 | 3 | 4 | class BlogConfig(AppConfig): 5 | name = 'blog' 6 | -------------------------------------------------------------------------------- /blog/forms.py: -------------------------------------------------------------------------------- 1 | from django import forms 2 | from django.contrib.auth.models import User 3 | 4 | from .models import Post, Comment 5 | from crispy_forms.helper import FormHelper 6 | from crispy_forms.layout import Submit 7 | 8 | 9 | class PostForm(forms.ModelForm): 10 | class Meta: 11 | model = Post 12 | fields = ('title', 'text') 13 | 14 | 15 | class CommentForm(forms.ModelForm): 16 | class Meta: 17 | model = Comment 18 | fields = ('text',) 19 | 20 | 21 | class UserForm(forms.ModelForm): 22 | password = forms.CharField(widget=forms.PasswordInput()) 23 | helper = FormHelper() 24 | helper.form_method = 'POST' 25 | helper.add_input(Submit('Sign up', 'Sign up', css_class='btn-primary')) 26 | class Meta: 27 | model = User 28 | fields = ('username', 'email', 'password',) -------------------------------------------------------------------------------- /blog/migrations/0001_initial.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.1 on 2018-08-04 06:38 2 | 3 | from django.conf import settings 4 | from django.db import migrations, models 5 | import django.db.models.deletion 6 | import django.utils.timezone 7 | 8 | 9 | class Migration(migrations.Migration): 10 | 11 | initial = True 12 | 13 | dependencies = [ 14 | migrations.swappable_dependency(settings.AUTH_USER_MODEL), 15 | ] 16 | 17 | operations = [ 18 | migrations.CreateModel( 19 | name='Post', 20 | fields=[ 21 | ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), 22 | ('title', models.CharField(max_length=200)), 23 | ('text', models.TextField()), 24 | ('created_date', models.DateTimeField(default=django.utils.timezone.now)), 25 | ('published_date', models.DateTimeField(blank=True, null=True)), 26 | ('author', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), 27 | ], 28 | ), 29 | ] 30 | -------------------------------------------------------------------------------- /blog/migrations/0002_comment.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.0.5 on 2018-08-12 06:04 2 | 3 | from django.db import migrations, models 4 | import django.db.models.deletion 5 | import django.utils.timezone 6 | 7 | 8 | class Migration(migrations.Migration): 9 | 10 | dependencies = [ 11 | ('blog', '0001_initial'), 12 | ] 13 | 14 | operations = [ 15 | migrations.CreateModel( 16 | name='Comment', 17 | fields=[ 18 | ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), 19 | ('author', models.CharField(max_length=200)), 20 | ('text', models.TextField()), 21 | ('created_date', models.DateTimeField(default=django.utils.timezone.now)), 22 | ('post', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='comments', to='blog.Post')), 23 | ], 24 | ), 25 | ] 26 | -------------------------------------------------------------------------------- /blog/migrations/0003_comment_approved.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.0.5 on 2018-08-12 07:27 2 | 3 | from django.db import migrations, models 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [ 9 | ('blog', '0002_comment'), 10 | ] 11 | 12 | operations = [ 13 | migrations.AddField( 14 | model_name='comment', 15 | name='approved', 16 | field=models.BooleanField(default=False), 17 | ), 18 | ] 19 | -------------------------------------------------------------------------------- /blog/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CleverProgrammer/my_django_site/e05a27b92015031a5edf383918981fb038ab9195/blog/migrations/__init__.py -------------------------------------------------------------------------------- /blog/models.py: -------------------------------------------------------------------------------- 1 | from django.db import models 2 | from django.utils import timezone 3 | 4 | # Create your models here. 5 | class Post(models.Model): 6 | author = models.ForeignKey('auth.User', on_delete=models.CASCADE) 7 | title = models.CharField(max_length=200) 8 | text = models.TextField() 9 | created_date = models.DateTimeField(default=timezone.now) 10 | published_date = models.DateTimeField(blank=True, null=True) 11 | 12 | def publish(self): 13 | self.published_date = timezone.now() 14 | self.save() 15 | 16 | def approved_comments(self): 17 | return self.comments.filter(approved=True) 18 | 19 | def __str__(self): 20 | return self.title 21 | 22 | 23 | class Comment(models.Model): 24 | post = models.ForeignKey('blog.Post', on_delete=models.CASCADE, related_name='comments') 25 | author = models.CharField(max_length=200) 26 | text = models.TextField() 27 | created_date = models.DateTimeField(default=timezone.now) 28 | approved = models.BooleanField(default=False) 29 | 30 | def approve(self): 31 | self.approved = True 32 | self.save() 33 | 34 | def __str__(self): 35 | return self.text 36 | -------------------------------------------------------------------------------- /blog/static/css/blog.css: -------------------------------------------------------------------------------- 1 | .page-header { 2 | background-color: #ff9400; 3 | margin-top: 0; 4 | padding: 20px 20px 20px 40px; 5 | } 6 | 7 | .page-header h1, .page-header h1 a{ 8 | color: #ffffff; 9 | font-size: 36pt; 10 | text-decoration: none; 11 | } 12 | 13 | .content { 14 | margin-left: 40px; 15 | } 16 | 17 | h1, h2, h3, h4 { 18 | font-family: 'Tangerine', 'Inconsolata', 'Droid Sans', serif; 19 | font-size: 48px; 20 | } 21 | 22 | .date { 23 | color: #828282; 24 | } 25 | 26 | .post { 27 | margin-bottom: 70px; 28 | } 29 | 30 | .post h1 a { 31 | color: #000000; 32 | } 33 | 34 | .post-form-blog textarea { 35 | width:100%; 36 | } 37 | 38 | .post-form-blog .btn-primary { 39 | float: right; 40 | } 41 | 42 | .top-menu, .top-menu:hover { 43 | color: #ffffff; 44 | float: right; 45 | font-size: 26pt; 46 | margin-right: 20px; 47 | } 48 | 49 | .comment { 50 | margin: 20px 0px 20px 20px; 51 | } 52 | -------------------------------------------------------------------------------- /blog/static/css/zenburn.css: -------------------------------------------------------------------------------- 1 | .highlight code, .highlight pre { 2 | color: #fdce93; 3 | background-color: #000000; 4 | font-family: 'Source Code Pro', sans-serif; 5 | font-size: 16px; 6 | } 7 | .highlight .hll { 8 | background-color: #222; 9 | } 10 | .highlight .err { 11 | color: #e37170; 12 | background-color: #3d3535; 13 | } 14 | .highlight .k { 15 | color: #f0dfaf; 16 | } 17 | .highlight .p { 18 | color: #41706f; 19 | } 20 | .highlight .cs { 21 | color: #cd0000; 22 | font-weight: 700; 23 | } 24 | .highlight .gd { 25 | color: #cd0000; 26 | } 27 | .highlight .ge { 28 | color: #ccc; 29 | font-style: italic; 30 | } 31 | .highlight .gr { 32 | color: red; 33 | } 34 | .highlight .go { 35 | color: gray; 36 | } 37 | .highlight .gs { 38 | color: #ccc; 39 | font-weight: 700; 40 | } 41 | .highlight .gu { 42 | color: purple; 43 | font-weight: 700; 44 | } 45 | .highlight .gt { 46 | color: #0040D0; 47 | } 48 | .highlight .kc { 49 | color: #dca3a3; 50 | } 51 | .highlight .kd { 52 | color: #ffff86; 53 | } 54 | .highlight .kn { 55 | color: #dfaf8f; 56 | font-weight: 700; 57 | } 58 | .highlight .kp { 59 | color: #cdcf99; 60 | } 61 | .highlight .kr { 62 | color: #cdcd00; 63 | } 64 | .highlight .ni { 65 | color: #c28182; 66 | } 67 | .highlight .ne { 68 | color: #c3bf9f; 69 | font-weight: 700; 70 | } 71 | .highlight .nn { 72 | color: #8fbede; 73 | } 74 | .highlight .vi { 75 | color: #ffffc7; 76 | } 77 | .highlight .c, .preview-zenburn .highlight .g, .preview-zenburn .highlight .cm, .preview-zenburn .highlight .cp, .preview-zenburn .highlight .c1 { 78 | color: #7f9f7f; 79 | } 80 | .highlight .l, .preview-zenburn .highlight .x, .preview-zenburn .highlight .no, .preview-zenburn .highlight .nd, .preview-zenburn .highlight .nl, .preview-zenburn .highlight .nx, .preview-zenburn .highlight .py, .preview-zenburn .highlight .w { 81 | color: #ccc; 82 | } 83 | .highlight .n, .preview-zenburn .highlight .nv, .preview-zenburn .highlight .vg { 84 | color: #dcdccc; 85 | } 86 | .highlight .o, .preview-zenburn .highlight .ow { 87 | color: #f0efd0; 88 | } 89 | .highlight .gh, .preview-zenburn .highlight .gp { 90 | color: #dcdccc; 91 | font-weight: 700; 92 | } 93 | .highlight .gi, .preview-zenburn .highlight .kt { 94 | color: #00cd00; 95 | } 96 | .highlight .ld, .preview-zenburn .highlight .s, .preview-zenburn .highlight .sb, .preview-zenburn .highlight .sc, .preview-zenburn .highlight .sd, .preview-zenburn .highlight .s2, .preview-zenburn .highlight .se, .preview-zenburn .highlight .sh, .preview-zenburn .highlight .si, .preview-zenburn .highlight .sx, .preview-zenburn .highlight .sr, .preview-zenburn .highlight .s1, .preview-zenburn .highlight .ss { 97 | color: #cc9393; 98 | } 99 | .highlight .m, .preview-zenburn .highlight .mf, .preview-zenburn .highlight .mh, .preview-zenburn .highlight .mi, .preview-zenburn .highlight .mo, .preview-zenburn .highlight .il { 100 | color: #8cd0d3; 101 | } 102 | .highlight .na, .preview-zenburn .highlight .nt { 103 | color: #9ac39f; 104 | } 105 | .highlight .nb, .preview-zenburn .highlight .nc, .preview-zenburn .highlight .nf, .preview-zenburn .highlight .bp, .preview-zenburn .highlight .vc { 106 | color: #efef8f; 107 | } -------------------------------------------------------------------------------- /blog/templates/blog/add_comment_to_post.html: -------------------------------------------------------------------------------- 1 | {% extends 'blog/base.html' %} 2 | 3 | {% block title %}Adding a Comment{% endblock %} 4 | 5 | {% block content %} 6 |

New comment

7 |
8 | {% csrf_token %} 9 | {{ form.as_p }} 10 | 11 |
12 | {% endblock %} -------------------------------------------------------------------------------- /blog/templates/blog/base.html: -------------------------------------------------------------------------------- 1 | {% load staticfiles %} 2 | 3 | 4 | 5 | 6 | {% block title %}{% endblock %} 7 | 9 | 10 | 11 | 12 | 14 | 15 | 16 | 17 | 18 | 34 | 35 |
36 |
37 |
38 | 39 | {% block content %} 40 | {% endblock %} 41 | 42 |
43 |
44 |
45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /blog/templates/blog/post_detail.html: -------------------------------------------------------------------------------- 1 | {% extends 'blog/base.html' %} 2 | {% load markdownify %} 3 | 4 | {% block title %}{{ post.title }}{% endblock %} 5 | 6 | {% block content %} 7 |
8 | 9 | {% if post.published_date %} 10 |
11 | {{ post.published_date }} 12 |
13 | 14 | {% else %} 15 | Publish 16 | 17 | {% endif %} 18 | 19 | {% if user.is_authenticated %} 20 | 21 | {% endif %} 22 | 24 | 25 | 26 | 27 | 28 |

{{ post.title }}

29 |

{{ post.text | markdown | safe }}

30 |
31 | 32 |
33 | Add comment 34 | {% for comment in post.comments.all %} 35 | {% if user.is_authenticated or comment.approved %} 36 |
37 | 38 |
39 | {{ comment.created_date }} 40 |
41 | 42 | {% if not comment.approved and user.is_superuser %} 43 | 44 | 45 | 46 | 47 | 48 | {% endif %} 49 | 50 | {{ comment.author }} 51 |

{{ comment.text | markdown | safe | linebreaksbr }}

52 |
53 | 54 | {% endif %} 55 | {% empty %} 56 |

No comments yet...

57 | 58 | {% endfor %} 59 | {% endblock %} 60 | -------------------------------------------------------------------------------- /blog/templates/blog/post_draft_list.html: -------------------------------------------------------------------------------- 1 | {% extends 'blog/base.html' %} 2 | 3 | {% block title %}My drafts{% endblock %} 4 | 5 | {% block content %} 6 | 7 | {% for post in posts %} 8 |
9 |

created: {{ post.created_date|date:'m-d-Y' }}

10 |

{{ post.title }}

11 |

{{ post.text|truncatechars:50 }}

12 |
13 | {% endfor %} 14 | 15 | {% endblock %} -------------------------------------------------------------------------------- /blog/templates/blog/post_edit.html: -------------------------------------------------------------------------------- 1 | {% extends 'blog/base.html' %} 2 | 3 | {% block title %}{{ post.title }}{% endblock %} 4 | 5 | {% block content %} 6 |

New Post

7 |
8 | {% csrf_token %} 9 | {{ form.as_p }} 10 | 11 |
12 | {% endblock %} -------------------------------------------------------------------------------- /blog/templates/blog/post_list.html: -------------------------------------------------------------------------------- 1 | {% extends 'blog/base.html' %} 2 | 3 | {% load markdownify %} 4 | 5 | {% block title %}My Blog{% endblock %} 6 | 7 | {% block content %} 8 | {% for post in posts %} 9 |
10 | 11 |
12 |

Published: {{ post.published_date }}

13 |
14 | 15 |

{{ post.title }}

16 |

{{ post.text| markdown | safe | linebreaksbr }}

17 | 18 | Comments: {{ post.approved_comments.count }} 19 |
20 | {% endfor %} 21 | {% endblock %} 22 | -------------------------------------------------------------------------------- /blog/templates/blog/signup.html: -------------------------------------------------------------------------------- 1 | {% extends 'blog/base.html' %} 2 | 3 | {% block title %}Signup{% endblock %} 4 | 5 | {% load crispy_forms_tags %} 6 | 7 | {% block content %} 8 |
9 |

Become a Clever Programmer Today.

10 |
11 | {% crispy form %} 12 |
13 |
14 | 15 | {% endblock %} 16 | -------------------------------------------------------------------------------- /blog/templates/registration/login.html: -------------------------------------------------------------------------------- 1 | {% extends 'blog/base.html' %} 2 | 3 | {% block title %}Login{% endblock %} 4 | 5 | {% block content %} 6 |

login

7 |
8 | {% csrf_token %} 9 | {{ form.as_p }} 10 | 11 |
12 |

Don't have an account? Sign Up Here

13 | {% endblock %} -------------------------------------------------------------------------------- /blog/templatetags/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CleverProgrammer/my_django_site/e05a27b92015031a5edf383918981fb038ab9195/blog/templatetags/__init__.py -------------------------------------------------------------------------------- /blog/templatetags/markdownify.py: -------------------------------------------------------------------------------- 1 | from django import template 2 | import mistune 3 | from pygments import highlight 4 | from pygments.lexers import get_lexer_by_name 5 | from pygments.formatters.html import HtmlFormatter 6 | 7 | register = template.Library() 8 | 9 | 10 | class HighlightRenderer(mistune.Renderer): 11 | def block_code(self, code, lang): 12 | if not lang: 13 | return '\n
%s
\n' % \ 14 | mistune.escape(code) 15 | lexer = get_lexer_by_name(lang, stripall=True) 16 | formatter = HtmlFormatter() 17 | return highlight(code, lexer, formatter) 18 | 19 | 20 | @register.filter 21 | def markdown(value): 22 | renderer = HighlightRenderer() 23 | markdown = mistune.Markdown(renderer=renderer) 24 | return markdown(value) 25 | -------------------------------------------------------------------------------- /blog/tests.py: -------------------------------------------------------------------------------- 1 | from django.test import TestCase 2 | 3 | # Create your tests here. 4 | -------------------------------------------------------------------------------- /blog/urls.py: -------------------------------------------------------------------------------- 1 | from django.urls import path 2 | from . import views 3 | 4 | urlpatterns = [ 5 | # 127.0.0.1:8000 --> local 6 | # mydjangosite.com --> online 7 | path('', views.post_list, name='post_list'), 8 | 9 | # 127.0.0.1:8000/post/2 --> local 10 | # mydjangosite.com/post/2 --> online 11 | path('post//', views.post_detail, name='post_detail'), 12 | 13 | # 127.0.0.1:8000/post/new --> local 14 | # mydjangosite.com/post/new --> online 15 | path('post/new/', views.post_new, name='post_new'), 16 | 17 | # 127.0.0.1:8000/post/2/edit --> local 18 | # mydjangosite.com/post/2/edit --> online 19 | path('post//edit/', views.post_edit, name='post_edit'), 20 | 21 | # 127.0.0.1:8000/post/2/delete --> local 22 | # mydjangosite.com/post/2/delete --> online 23 | path('post//delete/', views.post_delete, name='post_delete'), 24 | 25 | # 127.0.0.1:8000/drafts --> local 26 | # mydjangosite.com/drafts --> online 27 | path('drafts/', views.post_draft_list, name='post_draft_list'), 28 | 29 | # 127.0.0.1:8000/post/2/publish --> local 30 | # mydjangosite.com/post/2/publish --> online 31 | path('post//publish/', views.post_publish, name='post_publish'), 32 | 33 | # 127.0.0.1:8000/post/2/comment --> local 34 | # mydjangosite.com/post/2/comment --> online 35 | path('post//comment/', views.add_comment_to_post, name='add_comment_to_post'), 36 | 37 | # 127.0.0.1:8000/comment/2/remove --> local 38 | # mydjangosite.com/comment/2/remove --> online 39 | path('comment//remove/', views.comment_remove, name='comment_remove'), 40 | 41 | # 127.0.0.1:8000/comment/2/approve --> local 42 | # mydjangosite.com/comment/2/approve --> online 43 | path('comment//approve/', views.comment_approve, name='comment_approve'), 44 | 45 | # 127.0.0.1:8000/signup --> local 46 | # mydjangosite.com/signup --> online 47 | path('signup/', views.signup, name='signup'), 48 | ] 49 | -------------------------------------------------------------------------------- /blog/views.py: -------------------------------------------------------------------------------- 1 | from django.contrib.auth import login 2 | from django.contrib.auth.decorators import login_required 3 | from django.contrib.auth.models import User 4 | from django.shortcuts import render, get_object_or_404, redirect 5 | from django.utils import timezone 6 | 7 | from .forms import PostForm, CommentForm, UserForm 8 | from .models import Post, Comment 9 | 10 | 11 | # Create your views here. 12 | def post_list(request): 13 | posts = Post.objects.filter(published_date__lte=timezone.now()).order_by('-published_date') 14 | stuff_for_frontend = {'posts': posts} 15 | return render(request, 'blog/post_list.html', stuff_for_frontend) 16 | 17 | 18 | def post_detail(request, pk): 19 | post = get_object_or_404(Post, pk=pk) 20 | stuff_for_frontend = {'post': post} 21 | return render(request, 'blog/post_detail.html', stuff_for_frontend) 22 | 23 | 24 | @login_required 25 | def post_new(request): 26 | if request.method == 'POST': 27 | form = PostForm(request.POST) 28 | if form.is_valid(): 29 | post = form.save(commit=False) 30 | post.author = request.user 31 | post.save() 32 | return redirect('post_detail', pk=post.pk) 33 | else: 34 | form = PostForm() 35 | stuff_for_frontend = {'form': form} 36 | return render(request, 'blog/post_edit.html', stuff_for_frontend) 37 | 38 | @login_required 39 | def post_edit(request, pk): 40 | post = get_object_or_404(Post, pk=pk) 41 | if request.method == 'POST': 42 | 43 | # updating an existing form 44 | form = PostForm(request.POST, instance=post) 45 | 46 | if form.is_valid(): 47 | post = form.save(commit=False) 48 | post.author = request.user 49 | post.save() 50 | return redirect('post_detail', pk=post.pk) 51 | else: 52 | form = PostForm(instance=post) 53 | stuff_for_frontend = {'form': form, 'post': post} 54 | return render(request, 'blog/post_edit.html', stuff_for_frontend) 55 | 56 | @login_required 57 | def post_draft_list(request): 58 | posts = Post.objects.filter(published_date__isnull=True).order_by('-created_date') 59 | stuff_for_frontend = {'posts': posts} 60 | return render(request, 'blog/post_draft_list.html', stuff_for_frontend) 61 | 62 | @login_required 63 | def post_publish(request, pk): 64 | post = get_object_or_404(Post, pk=pk) 65 | post.publish() 66 | return redirect('post_detail', pk=pk) 67 | 68 | @login_required 69 | def post_delete(request, pk): 70 | post = get_object_or_404(Post, pk=pk) 71 | post.delete() 72 | return redirect('/', pk=post.pk) 73 | 74 | @login_required 75 | def add_comment_to_post(request, pk): 76 | post = get_object_or_404(Post, pk=pk) 77 | if request.method == 'POST': 78 | form = CommentForm(request.POST) 79 | if form.is_valid(): 80 | comment = form.save(commit=False) 81 | comment.author = request.user 82 | comment.post = post 83 | comment.save() 84 | return redirect('post_detail', pk=post.pk) 85 | else: 86 | form = CommentForm() 87 | return render(request, 'blog/add_comment_to_post.html', {'form': form}) 88 | 89 | 90 | @login_required 91 | def comment_remove(request, pk): 92 | comment = get_object_or_404(Comment, pk=pk) 93 | comment.delete() 94 | return redirect('post_detail', pk=comment.post.pk) 95 | 96 | 97 | @login_required 98 | def comment_approve(request, pk): 99 | # mydjangosite.com/comment/2/approve --> the 2nd comment will get approved 100 | comment = get_object_or_404(Comment, pk=pk) 101 | comment.approve() 102 | return redirect('post_detail', pk=comment.post.pk) 103 | 104 | def signup(request): 105 | if request.method == 'POST': 106 | form = UserForm(request.POST) 107 | if form.is_valid(): 108 | new_user = User.objects.create_user(**form.cleaned_data) 109 | login(request, new_user) 110 | return redirect('/') 111 | else: 112 | form = UserForm() 113 | return render(request, 'blog/signup.html', {'form': form}) -------------------------------------------------------------------------------- /db.sqlite3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CleverProgrammer/my_django_site/e05a27b92015031a5edf383918981fb038ab9195/db.sqlite3 -------------------------------------------------------------------------------- /manage.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | import os 3 | import sys 4 | 5 | if __name__ == "__main__": 6 | os.environ.setdefault("DJANGO_SETTINGS_MODULE", "mysite.settings") 7 | try: 8 | from django.core.management import execute_from_command_line 9 | except ImportError: 10 | # The above import may fail for some other reason. Ensure that the 11 | # issue is really that Django is missing to avoid masking other 12 | # exceptions on Python 2. 13 | try: 14 | import django 15 | except ImportError: 16 | raise ImportError( 17 | "Couldn't import Django. Are you sure it's installed and " 18 | "available on your PYTHONPATH environment variable? Did you " 19 | "forget to activate a virtual environment?" 20 | ) 21 | raise 22 | execute_from_command_line(sys.argv) 23 | -------------------------------------------------------------------------------- /mysite/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CleverProgrammer/my_django_site/e05a27b92015031a5edf383918981fb038ab9195/mysite/__init__.py -------------------------------------------------------------------------------- /mysite/__pycache__/__init__.cpython-36.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CleverProgrammer/my_django_site/e05a27b92015031a5edf383918981fb038ab9195/mysite/__pycache__/__init__.cpython-36.pyc -------------------------------------------------------------------------------- /mysite/__pycache__/settings.cpython-36.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CleverProgrammer/my_django_site/e05a27b92015031a5edf383918981fb038ab9195/mysite/__pycache__/settings.cpython-36.pyc -------------------------------------------------------------------------------- /mysite/settings.py: -------------------------------------------------------------------------------- 1 | """ 2 | Django settings for mysite project. 3 | 4 | Generated by 'django-admin startproject' using Django 1.10.7. 5 | 6 | For more information on this file, see 7 | https://docs.djangoproject.com/en/1.10/topics/settings/ 8 | 9 | For the full list of settings and their values, see 10 | https://docs.djangoproject.com/en/1.10/ref/settings/ 11 | """ 12 | 13 | import os 14 | 15 | # Build paths inside the project like this: os.path.join(BASE_DIR, ...) 16 | BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) 17 | 18 | 19 | # Quick-start development settings - unsuitable for production 20 | # See https://docs.djangoproject.com/en/1.10/howto/deployment/checklist/ 21 | 22 | # SECURITY WARNING: keep the secret key used in production secret! 23 | SECRET_KEY = 'v-z&921-$-p+n@t=d$qkpm&s6o0pe4j1s3zcta!u(59m8c8j9h' 24 | 25 | # SECURITY WARNING: don't run with debug turned on in production! 26 | DEBUG = True 27 | 28 | CRISPY_TEMPLATE_PACK = 'bootstrap3' 29 | 30 | ALLOWED_HOSTS = [] 31 | 32 | LOGIN_REDIRECT_URL = 'post_list' 33 | 34 | 35 | # Application definition 36 | 37 | INSTALLED_APPS = [ 38 | 'django.contrib.admin', 39 | 'django.contrib.auth', 40 | 'django.contrib.contenttypes', 41 | 'django.contrib.sessions', 42 | 'django.contrib.messages', 43 | 'django.contrib.staticfiles', 44 | 'blog', 45 | 'crispy_forms', 46 | ] 47 | 48 | MIDDLEWARE = [ 49 | 'django.middleware.security.SecurityMiddleware', 50 | 'django.contrib.sessions.middleware.SessionMiddleware', 51 | 'django.middleware.common.CommonMiddleware', 52 | 'django.middleware.csrf.CsrfViewMiddleware', 53 | 'django.contrib.auth.middleware.AuthenticationMiddleware', 54 | 'django.contrib.messages.middleware.MessageMiddleware', 55 | 'django.middleware.clickjacking.XFrameOptionsMiddleware', 56 | ] 57 | 58 | ROOT_URLCONF = 'mysite.urls' 59 | 60 | TEMPLATES = [ 61 | { 62 | 'BACKEND': 'django.template.backends.django.DjangoTemplates', 63 | 'DIRS': [], 64 | 'APP_DIRS': True, 65 | 'OPTIONS': { 66 | 'context_processors': [ 67 | 'django.template.context_processors.debug', 68 | 'django.template.context_processors.request', 69 | 'django.contrib.auth.context_processors.auth', 70 | 'django.contrib.messages.context_processors.messages', 71 | ], 72 | }, 73 | }, 74 | ] 75 | 76 | WSGI_APPLICATION = 'mysite.wsgi.application' 77 | 78 | 79 | # Database 80 | # https://docs.djangoproject.com/en/1.10/ref/settings/#databases 81 | 82 | DATABASES = { 83 | 'default': { 84 | 'ENGINE': 'django.db.backends.sqlite3', 85 | 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'), 86 | } 87 | } 88 | 89 | 90 | # Password validation 91 | # https://docs.djangoproject.com/en/1.10/ref/settings/#auth-password-validators 92 | 93 | AUTH_PASSWORD_VALIDATORS = [ 94 | { 95 | 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator', 96 | }, 97 | { 98 | 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator', 99 | }, 100 | { 101 | 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator', 102 | }, 103 | { 104 | 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator', 105 | }, 106 | ] 107 | 108 | 109 | # Internationalization 110 | # https://docs.djangoproject.com/en/1.10/topics/i18n/ 111 | 112 | LANGUAGE_CODE = 'en-us' 113 | 114 | TIME_ZONE = 'America/Los_Angeles' 115 | 116 | USE_I18N = True 117 | 118 | USE_L10N = True 119 | 120 | USE_TZ = True 121 | 122 | 123 | # Static files (CSS, JavaScript, Images) 124 | # https://docs.djangoproject.com/en/1.10/howto/static-files/ 125 | 126 | STATIC_URL = '/static/' 127 | -------------------------------------------------------------------------------- /mysite/urls.py: -------------------------------------------------------------------------------- 1 | """mysite URL Configuration 2 | 3 | The `urlpatterns` list routes URLs to views. For more information please see: 4 | https://docs.djangoproject.com/en/1.10/topics/http/urls/ 5 | Examples: 6 | Function views 7 | 1. Add an import: from my_app import views 8 | 2. Add a URL to urlpatterns: url(r'^$', views.home, name='home') 9 | Class-based views 10 | 1. Add an import: from other_app.views import Home 11 | 2. Add a URL to urlpatterns: url(r'^$', Home.as_view(), name='home') 12 | Including another URLconf 13 | 1. Import the include() function: from django.conf.urls import url, include 14 | 2. Add a URL to urlpatterns: url(r'^blog/', include('blog.urls')) 15 | """ 16 | from django.urls import path, include 17 | from django.contrib import admin 18 | from django.contrib.auth import views as auth_views 19 | 20 | urlpatterns = [ 21 | path('admin/', admin.site.urls), 22 | 23 | # 127.0.0.1:8000/accounts/login --> local 24 | # mydjangosite.com/accounts/login --> online 25 | path('accounts/login/', auth_views.login, name='login'), 26 | 27 | # 127.0.0.1:8000/accounts/logout --> local 28 | # mydjangosite.com/accounts/logout --> online 29 | path('accounts/logout/', view=auth_views.logout, name='logout', kwargs={'next_page': 'post_list'}), 30 | 31 | # 127.0.0.1:8000 32 | path('', include('blog.urls')), 33 | ] 34 | -------------------------------------------------------------------------------- /mysite/wsgi.py: -------------------------------------------------------------------------------- 1 | """ 2 | WSGI config for mysite project. 3 | 4 | It exposes the WSGI callable as a module-level variable named ``application``. 5 | 6 | For more information on this file, see 7 | https://docs.djangoproject.com/en/1.10/howto/deployment/wsgi/ 8 | """ 9 | 10 | import os 11 | 12 | from django.core.wsgi import get_wsgi_application 13 | 14 | os.environ.setdefault("DJANGO_SETTINGS_MODULE", "mysite.settings") 15 | 16 | application = get_wsgi_application() 17 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | certifi==2018.4.16 2 | Django==2.1 3 | django-crispy-forms==1.7.2 4 | Markdown==2.6.11 5 | mistune==0.8.3 6 | Pygments==2.2.0 7 | pytz==2018.5 8 | --------------------------------------------------------------------------------