├── .idea
├── .gitignore
├── A.iml
├── inspectionProfiles
│ └── profiles_settings.xml
├── misc.xml
├── modules.xml
└── vcs.xml
├── A
├── __init__.py
├── __pycache__
│ ├── __init__.cpython-310.pyc
│ ├── __init__.cpython-37.pyc
│ ├── settings.cpython-310.pyc
│ ├── settings.cpython-37.pyc
│ ├── urls.cpython-310.pyc
│ ├── urls.cpython-37.pyc
│ ├── wsgi.cpython-310.pyc
│ └── wsgi.cpython-37.pyc
├── asgi.py
├── settings.py
├── urls.py
└── wsgi.py
├── Dockerfile
├── accounts
├── __init__.py
├── __pycache__
│ ├── __init__.cpython-310.pyc
│ ├── __init__.cpython-37.pyc
│ ├── admin.cpython-310.pyc
│ ├── admin.cpython-37.pyc
│ ├── apps.cpython-310.pyc
│ ├── apps.cpython-37.pyc
│ ├── authenticate.cpython-37.pyc
│ ├── forms.cpython-310.pyc
│ ├── forms.cpython-37.pyc
│ ├── models.cpython-310.pyc
│ ├── models.cpython-37.pyc
│ ├── urls.cpython-310.pyc
│ ├── urls.cpython-37.pyc
│ ├── views.cpython-310.pyc
│ └── views.cpython-37.pyc
├── admin.py
├── apps.py
├── authenticate.py
├── forms.py
├── migrations
│ ├── __init__.py
│ └── __pycache__
│ │ ├── __init__.cpython-310.pyc
│ │ └── __init__.cpython-37.pyc
├── models.py
├── templates
│ └── accounts
│ │ ├── login.html
│ │ └── register.html
├── tests.py
├── urls.py
└── views.py
├── blog
├── __init__.py
├── __pycache__
│ ├── __init__.cpython-310.pyc
│ ├── __init__.cpython-37.pyc
│ ├── admin.cpython-310.pyc
│ ├── admin.cpython-37.pyc
│ ├── apps.cpython-310.pyc
│ ├── apps.cpython-37.pyc
│ ├── models.cpython-310.pyc
│ ├── models.cpython-37.pyc
│ ├── urls.cpython-310.pyc
│ ├── urls.cpython-37.pyc
│ ├── views.cpython-310.pyc
│ └── views.cpython-37.pyc
├── admin.py
├── apps.py
├── migrations
│ ├── 0001_initial.py
│ ├── 0002_auto_20191217_0829.py
│ ├── __init__.py
│ └── __pycache__
│ │ ├── 0001_initial.cpython-310.pyc
│ │ ├── 0001_initial.cpython-37.pyc
│ │ ├── 0002_auto_20191217_0829.cpython-310.pyc
│ │ ├── 0002_auto_20191217_0829.cpython-37.pyc
│ │ ├── __init__.cpython-310.pyc
│ │ └── __init__.cpython-37.pyc
├── models.py
├── static
│ └── blog
│ │ └── css
│ │ └── style.css
├── templates
│ └── blog
│ │ ├── all_articles.html
│ │ └── article.html
├── tests.py
├── urls.py
└── views.py
├── db.sqlite3
├── docker-compose.yml
├── manage.py
├── media
└── uploads
│ └── 2019
│ └── 12
│ └── 17
│ ├── sql-course.png
│ └── sql-course_FVmVYxj.png
├── nginx.conf
├── requirements.txt
└── templates
├── 404.html
├── base.html
└── inc
├── messages.html
└── navbar.html
/.idea/.gitignore:
--------------------------------------------------------------------------------
1 | # Default ignored files
2 | /workspace.xml
--------------------------------------------------------------------------------
/.idea/A.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/.idea/inspectionProfiles/profiles_settings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/A/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/amirbigg/django-blog/23d6d47dd3e309fa736cd891654a09da18d08427/A/__init__.py
--------------------------------------------------------------------------------
/A/__pycache__/__init__.cpython-310.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/amirbigg/django-blog/23d6d47dd3e309fa736cd891654a09da18d08427/A/__pycache__/__init__.cpython-310.pyc
--------------------------------------------------------------------------------
/A/__pycache__/__init__.cpython-37.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/amirbigg/django-blog/23d6d47dd3e309fa736cd891654a09da18d08427/A/__pycache__/__init__.cpython-37.pyc
--------------------------------------------------------------------------------
/A/__pycache__/settings.cpython-310.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/amirbigg/django-blog/23d6d47dd3e309fa736cd891654a09da18d08427/A/__pycache__/settings.cpython-310.pyc
--------------------------------------------------------------------------------
/A/__pycache__/settings.cpython-37.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/amirbigg/django-blog/23d6d47dd3e309fa736cd891654a09da18d08427/A/__pycache__/settings.cpython-37.pyc
--------------------------------------------------------------------------------
/A/__pycache__/urls.cpython-310.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/amirbigg/django-blog/23d6d47dd3e309fa736cd891654a09da18d08427/A/__pycache__/urls.cpython-310.pyc
--------------------------------------------------------------------------------
/A/__pycache__/urls.cpython-37.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/amirbigg/django-blog/23d6d47dd3e309fa736cd891654a09da18d08427/A/__pycache__/urls.cpython-37.pyc
--------------------------------------------------------------------------------
/A/__pycache__/wsgi.cpython-310.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/amirbigg/django-blog/23d6d47dd3e309fa736cd891654a09da18d08427/A/__pycache__/wsgi.cpython-310.pyc
--------------------------------------------------------------------------------
/A/__pycache__/wsgi.cpython-37.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/amirbigg/django-blog/23d6d47dd3e309fa736cd891654a09da18d08427/A/__pycache__/wsgi.cpython-37.pyc
--------------------------------------------------------------------------------
/A/asgi.py:
--------------------------------------------------------------------------------
1 | """
2 | ASGI config for A project.
3 |
4 | It exposes the ASGI callable as a module-level variable named ``application``.
5 |
6 | For more information on this file, see
7 | https://docs.djangoproject.com/en/3.0/howto/deployment/asgi/
8 | """
9 |
10 | import os
11 |
12 | from django.core.asgi import get_asgi_application
13 |
14 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'A.settings')
15 |
16 | application = get_asgi_application()
17 |
--------------------------------------------------------------------------------
/A/settings.py:
--------------------------------------------------------------------------------
1 | import os
2 | BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
3 | SECRET_KEY = 'fpefnch#*pj%ada9ktt67xwfb+uwg8uj^750(h#^l(p761au^!'
4 | DEBUG = False
5 | ALLOWED_HOSTS = ["*"]
6 |
7 |
8 |
9 | # Application definition
10 |
11 | INSTALLED_APPS = [
12 | 'django.contrib.admin',
13 | 'django.contrib.auth',
14 | 'django.contrib.contenttypes',
15 | 'django.contrib.sessions',
16 | 'django.contrib.messages',
17 | 'django.contrib.staticfiles',
18 | 'blog.apps.BlogConfig',
19 | 'accounts.apps.AccountsConfig',
20 | 'ckeditor',
21 | 'ckeditor_uploader',
22 | ]
23 |
24 | MIDDLEWARE = [
25 | 'django.middleware.security.SecurityMiddleware',
26 | 'django.contrib.sessions.middleware.SessionMiddleware',
27 | 'django.middleware.common.CommonMiddleware',
28 | 'django.middleware.csrf.CsrfViewMiddleware',
29 | 'django.contrib.auth.middleware.AuthenticationMiddleware',
30 | 'django.contrib.messages.middleware.MessageMiddleware',
31 | 'django.middleware.clickjacking.XFrameOptionsMiddleware',
32 | ]
33 |
34 | ROOT_URLCONF = 'A.urls'
35 |
36 | TEMPLATES = [
37 | {
38 | 'BACKEND': 'django.template.backends.django.DjangoTemplates',
39 | 'DIRS': [os.path.join(BASE_DIR, 'templates')],
40 | 'APP_DIRS': True,
41 | 'OPTIONS': {
42 | 'context_processors': [
43 | 'django.template.context_processors.debug',
44 | 'django.template.context_processors.request',
45 | 'django.contrib.auth.context_processors.auth',
46 | 'django.contrib.messages.context_processors.messages',
47 | ],
48 | },
49 | },
50 | ]
51 |
52 | WSGI_APPLICATION = 'A.wsgi.application'
53 |
54 | AUTHENTICATION_BACKENDS = [
55 | 'django.contrib.auth.backends.ModelBackend',
56 | 'accounts.authenticate.EmailAuthBackend',
57 | ]
58 |
59 | # Database
60 | # https://docs.djangoproject.com/en/3.0/ref/settings/#databases
61 |
62 | DATABASES = {
63 | 'default': {
64 | 'ENGINE': 'django.db.backends.sqlite3',
65 | 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
66 | }
67 | }
68 |
69 |
70 | # Password validation
71 | # https://docs.djangoproject.com/en/3.0/ref/settings/#auth-password-validators
72 |
73 | AUTH_PASSWORD_VALIDATORS = [
74 | {
75 | 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
76 | },
77 | {
78 | 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
79 | },
80 | {
81 | 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
82 | },
83 | {
84 | 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
85 | },
86 | ]
87 |
88 |
89 | # Internationalization
90 | # https://docs.djangoproject.com/en/3.0/topics/i18n/
91 |
92 | LANGUAGE_CODE = 'en-us'
93 |
94 | TIME_ZONE = 'UTC'
95 |
96 | USE_I18N = True
97 |
98 | USE_L10N = True
99 |
100 | USE_TZ = True
101 |
102 |
103 | # Static files (CSS, JavaScript, Images)
104 | # https://docs.djangoproject.com/en/3.0/howto/static-files/
105 |
106 | STATIC_URL = '/static/'
107 | STATICFILES_DIRS = [
108 | os.path.join(BASE_DIR, "static"),
109 | ]
110 |
111 | MEDIA_ROOT = os.path.join(BASE_DIR, 'media/')
112 | MEDIA_URL = '/media/'
113 |
114 |
115 | CKEDITOR_UPLOAD_PATH = "uploads/"
116 | CKEDITOR_CONFIGS = {
117 | 'default': {
118 | 'toolbar': 'full',
119 | },
120 | }
--------------------------------------------------------------------------------
/A/urls.py:
--------------------------------------------------------------------------------
1 | from django.contrib import admin
2 | from django.urls import path, include
3 | from django.conf import settings
4 | from django.conf.urls.static import static
5 |
6 |
7 | urlpatterns = [
8 | path('admin/', admin.site.urls),
9 | path('', include('blog.urls', namespace='blog')),
10 | path('accounts/', include('accounts.urls', namespace='accounts')),
11 | path('ckeditor/', include('ckeditor_uploader.urls')),
12 | ] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
13 |
--------------------------------------------------------------------------------
/A/wsgi.py:
--------------------------------------------------------------------------------
1 | """
2 | WSGI config for A 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/3.0/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', 'A.settings')
15 |
16 | application = get_wsgi_application()
17 |
--------------------------------------------------------------------------------
/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM python:latest
2 |
3 | WORKDIR /code
4 |
5 | COPY requirements.txt /code/
6 |
7 | RUN pip install -U pip
8 | RUN pip install -r requirements.txt
9 |
10 | COPY . /code/
11 |
12 | CMD ["gunicorn", "A.wsgi", ":8000"]
--------------------------------------------------------------------------------
/accounts/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/amirbigg/django-blog/23d6d47dd3e309fa736cd891654a09da18d08427/accounts/__init__.py
--------------------------------------------------------------------------------
/accounts/__pycache__/__init__.cpython-310.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/amirbigg/django-blog/23d6d47dd3e309fa736cd891654a09da18d08427/accounts/__pycache__/__init__.cpython-310.pyc
--------------------------------------------------------------------------------
/accounts/__pycache__/__init__.cpython-37.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/amirbigg/django-blog/23d6d47dd3e309fa736cd891654a09da18d08427/accounts/__pycache__/__init__.cpython-37.pyc
--------------------------------------------------------------------------------
/accounts/__pycache__/admin.cpython-310.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/amirbigg/django-blog/23d6d47dd3e309fa736cd891654a09da18d08427/accounts/__pycache__/admin.cpython-310.pyc
--------------------------------------------------------------------------------
/accounts/__pycache__/admin.cpython-37.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/amirbigg/django-blog/23d6d47dd3e309fa736cd891654a09da18d08427/accounts/__pycache__/admin.cpython-37.pyc
--------------------------------------------------------------------------------
/accounts/__pycache__/apps.cpython-310.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/amirbigg/django-blog/23d6d47dd3e309fa736cd891654a09da18d08427/accounts/__pycache__/apps.cpython-310.pyc
--------------------------------------------------------------------------------
/accounts/__pycache__/apps.cpython-37.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/amirbigg/django-blog/23d6d47dd3e309fa736cd891654a09da18d08427/accounts/__pycache__/apps.cpython-37.pyc
--------------------------------------------------------------------------------
/accounts/__pycache__/authenticate.cpython-37.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/amirbigg/django-blog/23d6d47dd3e309fa736cd891654a09da18d08427/accounts/__pycache__/authenticate.cpython-37.pyc
--------------------------------------------------------------------------------
/accounts/__pycache__/forms.cpython-310.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/amirbigg/django-blog/23d6d47dd3e309fa736cd891654a09da18d08427/accounts/__pycache__/forms.cpython-310.pyc
--------------------------------------------------------------------------------
/accounts/__pycache__/forms.cpython-37.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/amirbigg/django-blog/23d6d47dd3e309fa736cd891654a09da18d08427/accounts/__pycache__/forms.cpython-37.pyc
--------------------------------------------------------------------------------
/accounts/__pycache__/models.cpython-310.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/amirbigg/django-blog/23d6d47dd3e309fa736cd891654a09da18d08427/accounts/__pycache__/models.cpython-310.pyc
--------------------------------------------------------------------------------
/accounts/__pycache__/models.cpython-37.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/amirbigg/django-blog/23d6d47dd3e309fa736cd891654a09da18d08427/accounts/__pycache__/models.cpython-37.pyc
--------------------------------------------------------------------------------
/accounts/__pycache__/urls.cpython-310.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/amirbigg/django-blog/23d6d47dd3e309fa736cd891654a09da18d08427/accounts/__pycache__/urls.cpython-310.pyc
--------------------------------------------------------------------------------
/accounts/__pycache__/urls.cpython-37.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/amirbigg/django-blog/23d6d47dd3e309fa736cd891654a09da18d08427/accounts/__pycache__/urls.cpython-37.pyc
--------------------------------------------------------------------------------
/accounts/__pycache__/views.cpython-310.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/amirbigg/django-blog/23d6d47dd3e309fa736cd891654a09da18d08427/accounts/__pycache__/views.cpython-310.pyc
--------------------------------------------------------------------------------
/accounts/__pycache__/views.cpython-37.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/amirbigg/django-blog/23d6d47dd3e309fa736cd891654a09da18d08427/accounts/__pycache__/views.cpython-37.pyc
--------------------------------------------------------------------------------
/accounts/admin.py:
--------------------------------------------------------------------------------
1 | from django.contrib import admin
2 |
3 | # Register your models here.
4 |
--------------------------------------------------------------------------------
/accounts/apps.py:
--------------------------------------------------------------------------------
1 | from django.apps import AppConfig
2 |
3 |
4 | class AccountsConfig(AppConfig):
5 | name = 'accounts'
6 |
--------------------------------------------------------------------------------
/accounts/authenticate.py:
--------------------------------------------------------------------------------
1 | from django.contrib.auth.models import User
2 |
3 |
4 | class EmailAuthBackend:
5 | def authenticate(self, request, username=None, password=None):
6 | try:
7 | user = User.objects.get(email=username)
8 | if user.check_password(password):
9 | return user
10 | return None
11 | except User.DoesNotExist:
12 | return None
13 |
14 |
15 | def get_user(self, user_id):
16 | try:
17 | return User.objects.get(pk=user_id)
18 | except User.DoesNotExist:
19 | return None
20 |
--------------------------------------------------------------------------------
/accounts/forms.py:
--------------------------------------------------------------------------------
1 | from django import forms
2 | from django.contrib.auth.models import User
3 |
4 |
5 | class UserLoginForm(forms.Form):
6 | username = forms.CharField(max_length=30, widget=forms.TextInput(attrs={'class':'form-control', 'placeholder':'Your username'}))
7 | password = forms.CharField(max_length=50, widget=forms.PasswordInput(attrs={'class':'form-control', 'placeholder':'Your password'}))
8 |
9 |
10 | class UserRegistrationForm(forms.Form):
11 | username = forms.CharField(max_length=30, widget=forms.TextInput(attrs={'class': 'form-control', 'placeholder': 'Your username'}))
12 | email = forms.EmailField(max_length=50, widget=forms.EmailInput(attrs={'class':'form-control', 'placeholder':'Your Email'}))
13 | password1 = forms.CharField(label='password', max_length=50, widget=forms.PasswordInput(attrs={'class': 'form-control', 'placeholder': 'Your password'}))
14 | password2 = forms.CharField(label='confirm password', max_length=50, widget=forms.PasswordInput(attrs={'class': 'form-control', 'placeholder': 'Your password'}))
15 |
16 | def clean_email(self):
17 | email = self.cleaned_data['email']
18 | user = User.objects.filter(email=email)
19 | if user.exists():
20 | raise forms.ValidationError('This email already exists')
21 | return email
22 |
23 | # def clean_password2(self):
24 | # p1 = self.cleaned_data['password1']
25 | # p2 = self.cleaned_data['password2']
26 | #
27 | # if p1 != p2:
28 | # raise forms.ValidationError('passwords must match')
29 | # return p1
30 |
31 | def clean(self):
32 | cleaned_data = super().clean()
33 | p1 = cleaned_data.get('password1')
34 | p2 = cleaned_data.get('password2')
35 |
36 | if p1 and p2:
37 | if p1 != p2:
38 | raise forms.ValidationError('passwords must match')
--------------------------------------------------------------------------------
/accounts/migrations/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/amirbigg/django-blog/23d6d47dd3e309fa736cd891654a09da18d08427/accounts/migrations/__init__.py
--------------------------------------------------------------------------------
/accounts/migrations/__pycache__/__init__.cpython-310.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/amirbigg/django-blog/23d6d47dd3e309fa736cd891654a09da18d08427/accounts/migrations/__pycache__/__init__.cpython-310.pyc
--------------------------------------------------------------------------------
/accounts/migrations/__pycache__/__init__.cpython-37.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/amirbigg/django-blog/23d6d47dd3e309fa736cd891654a09da18d08427/accounts/migrations/__pycache__/__init__.cpython-37.pyc
--------------------------------------------------------------------------------
/accounts/models.py:
--------------------------------------------------------------------------------
1 | from django.db import models
2 |
3 | # Create your models here.
4 |
--------------------------------------------------------------------------------
/accounts/templates/accounts/login.html:
--------------------------------------------------------------------------------
1 | {% extends 'base.html' %}
2 |
3 | {% block content %}
4 |
9 |
10 | {% endblock %}
--------------------------------------------------------------------------------
/accounts/templates/accounts/register.html:
--------------------------------------------------------------------------------
1 | {% extends 'base.html' %}
2 |
3 | {% block content %}
4 |
9 | {% endblock %}
--------------------------------------------------------------------------------
/accounts/tests.py:
--------------------------------------------------------------------------------
1 | from django.test import TestCase
2 |
3 | # Create your tests here.
4 |
--------------------------------------------------------------------------------
/accounts/urls.py:
--------------------------------------------------------------------------------
1 | from django.urls import path
2 | from . import views
3 |
4 |
5 | app_name = 'accounts'
6 | urlpatterns = [
7 | path('login/', views.user_login, name='user_login'),
8 | path('register/', views.user_register, name='user_register'),
9 | path('logout/', views.user_logout, name='user_logout'),
10 | ]
--------------------------------------------------------------------------------
/accounts/views.py:
--------------------------------------------------------------------------------
1 | from django.shortcuts import render, redirect
2 | from .forms import UserLoginForm, UserRegistrationForm
3 | from django.contrib.auth import authenticate, login, logout
4 | from django.contrib import messages
5 | from django.contrib.auth.models import User
6 |
7 |
8 | def user_login(request):
9 | if request.method == 'POST':
10 | form = UserLoginForm(request.POST)
11 | if form.is_valid():
12 | username = form.cleaned_data['username']
13 | password = form.cleaned_data['password']
14 | user = authenticate(request, username=username, password=password)
15 | if user is not None:
16 | login(request, user)
17 | messages.success(request, 'you logged in successfully', 'success')
18 | return redirect('blog:all_articles')
19 | else:
20 | messages.error(request, 'wrong username or password', 'warning')
21 | else:
22 | form = UserLoginForm()
23 | return render(request, 'accounts/login.html', {'form':form})
24 |
25 | def user_register(request):
26 | if request.method == 'POST':
27 | form = UserRegistrationForm(request.POST)
28 | if form.is_valid():
29 | cd = form.cleaned_data
30 | User.objects.create_user(cd['username'], cd['email'], cd['password1'])
31 | messages.success(request, 'you registered successfully, now log in', 'success')
32 | return redirect('accounts:user_login')
33 | else:
34 | form = UserRegistrationForm()
35 | return render(request, 'accounts/register.html', {'form':form})
36 |
37 | def user_logout(request):
38 | logout(request)
39 | messages.success(request, 'you logged out successfully', 'success')
40 | return redirect('blog:all_articles')
--------------------------------------------------------------------------------
/blog/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/amirbigg/django-blog/23d6d47dd3e309fa736cd891654a09da18d08427/blog/__init__.py
--------------------------------------------------------------------------------
/blog/__pycache__/__init__.cpython-310.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/amirbigg/django-blog/23d6d47dd3e309fa736cd891654a09da18d08427/blog/__pycache__/__init__.cpython-310.pyc
--------------------------------------------------------------------------------
/blog/__pycache__/__init__.cpython-37.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/amirbigg/django-blog/23d6d47dd3e309fa736cd891654a09da18d08427/blog/__pycache__/__init__.cpython-37.pyc
--------------------------------------------------------------------------------
/blog/__pycache__/admin.cpython-310.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/amirbigg/django-blog/23d6d47dd3e309fa736cd891654a09da18d08427/blog/__pycache__/admin.cpython-310.pyc
--------------------------------------------------------------------------------
/blog/__pycache__/admin.cpython-37.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/amirbigg/django-blog/23d6d47dd3e309fa736cd891654a09da18d08427/blog/__pycache__/admin.cpython-37.pyc
--------------------------------------------------------------------------------
/blog/__pycache__/apps.cpython-310.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/amirbigg/django-blog/23d6d47dd3e309fa736cd891654a09da18d08427/blog/__pycache__/apps.cpython-310.pyc
--------------------------------------------------------------------------------
/blog/__pycache__/apps.cpython-37.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/amirbigg/django-blog/23d6d47dd3e309fa736cd891654a09da18d08427/blog/__pycache__/apps.cpython-37.pyc
--------------------------------------------------------------------------------
/blog/__pycache__/models.cpython-310.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/amirbigg/django-blog/23d6d47dd3e309fa736cd891654a09da18d08427/blog/__pycache__/models.cpython-310.pyc
--------------------------------------------------------------------------------
/blog/__pycache__/models.cpython-37.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/amirbigg/django-blog/23d6d47dd3e309fa736cd891654a09da18d08427/blog/__pycache__/models.cpython-37.pyc
--------------------------------------------------------------------------------
/blog/__pycache__/urls.cpython-310.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/amirbigg/django-blog/23d6d47dd3e309fa736cd891654a09da18d08427/blog/__pycache__/urls.cpython-310.pyc
--------------------------------------------------------------------------------
/blog/__pycache__/urls.cpython-37.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/amirbigg/django-blog/23d6d47dd3e309fa736cd891654a09da18d08427/blog/__pycache__/urls.cpython-37.pyc
--------------------------------------------------------------------------------
/blog/__pycache__/views.cpython-310.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/amirbigg/django-blog/23d6d47dd3e309fa736cd891654a09da18d08427/blog/__pycache__/views.cpython-310.pyc
--------------------------------------------------------------------------------
/blog/__pycache__/views.cpython-37.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/amirbigg/django-blog/23d6d47dd3e309fa736cd891654a09da18d08427/blog/__pycache__/views.cpython-37.pyc
--------------------------------------------------------------------------------
/blog/admin.py:
--------------------------------------------------------------------------------
1 | from django.contrib import admin
2 | from .models import Article
3 |
4 | @admin.register(Article)
5 | class ArticleAdmin(admin.ModelAdmin):
6 | list_display = ('title', 'writer', 'publish', 'status')
7 | list_filter = ('status', 'writer', 'publish')
8 | list_editable = ('status',)
9 | search_fields = ('title', 'body')
10 | raw_id_fields = ('writer',)
11 | prepopulated_fields = {'slug':('title',)}
12 |
--------------------------------------------------------------------------------
/blog/apps.py:
--------------------------------------------------------------------------------
1 | from django.apps import AppConfig
2 |
3 |
4 | class BlogConfig(AppConfig):
5 | name = 'blog'
6 |
--------------------------------------------------------------------------------
/blog/migrations/0001_initial.py:
--------------------------------------------------------------------------------
1 | # Generated by Django 3.0 on 2019-12-11 17:10
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='Article',
20 | fields=[
21 | ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
22 | ('title', models.CharField(max_length=120)),
23 | ('slug', models.SlugField(max_length=120, unique=True)),
24 | ('body', models.TextField()),
25 | ('publish', models.DateTimeField(default=django.utils.timezone.now)),
26 | ('created', models.DateTimeField(auto_now_add=True)),
27 | ('updated', models.DateTimeField(auto_now=True)),
28 | ('status', models.CharField(choices=[('draft', 'Draft'), ('publish', 'Publish')], default='draft', max_length=20)),
29 | ('writer', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
30 | ],
31 | ),
32 | ]
33 |
--------------------------------------------------------------------------------
/blog/migrations/0002_auto_20191217_0829.py:
--------------------------------------------------------------------------------
1 | # Generated by Django 3.0 on 2019-12-17 08:29
2 |
3 | import ckeditor_uploader.fields
4 | from django.db import migrations
5 |
6 |
7 | class Migration(migrations.Migration):
8 |
9 | dependencies = [
10 | ('blog', '0001_initial'),
11 | ]
12 |
13 | operations = [
14 | migrations.AlterField(
15 | model_name='article',
16 | name='body',
17 | field=ckeditor_uploader.fields.RichTextUploadingField(),
18 | ),
19 | ]
20 |
--------------------------------------------------------------------------------
/blog/migrations/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/amirbigg/django-blog/23d6d47dd3e309fa736cd891654a09da18d08427/blog/migrations/__init__.py
--------------------------------------------------------------------------------
/blog/migrations/__pycache__/0001_initial.cpython-310.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/amirbigg/django-blog/23d6d47dd3e309fa736cd891654a09da18d08427/blog/migrations/__pycache__/0001_initial.cpython-310.pyc
--------------------------------------------------------------------------------
/blog/migrations/__pycache__/0001_initial.cpython-37.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/amirbigg/django-blog/23d6d47dd3e309fa736cd891654a09da18d08427/blog/migrations/__pycache__/0001_initial.cpython-37.pyc
--------------------------------------------------------------------------------
/blog/migrations/__pycache__/0002_auto_20191217_0829.cpython-310.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/amirbigg/django-blog/23d6d47dd3e309fa736cd891654a09da18d08427/blog/migrations/__pycache__/0002_auto_20191217_0829.cpython-310.pyc
--------------------------------------------------------------------------------
/blog/migrations/__pycache__/0002_auto_20191217_0829.cpython-37.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/amirbigg/django-blog/23d6d47dd3e309fa736cd891654a09da18d08427/blog/migrations/__pycache__/0002_auto_20191217_0829.cpython-37.pyc
--------------------------------------------------------------------------------
/blog/migrations/__pycache__/__init__.cpython-310.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/amirbigg/django-blog/23d6d47dd3e309fa736cd891654a09da18d08427/blog/migrations/__pycache__/__init__.cpython-310.pyc
--------------------------------------------------------------------------------
/blog/migrations/__pycache__/__init__.cpython-37.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/amirbigg/django-blog/23d6d47dd3e309fa736cd891654a09da18d08427/blog/migrations/__pycache__/__init__.cpython-37.pyc
--------------------------------------------------------------------------------
/blog/models.py:
--------------------------------------------------------------------------------
1 | from django.db import models
2 | from django.utils import timezone
3 | from django.contrib.auth.models import User
4 | from django.urls import reverse
5 | from ckeditor_uploader.fields import RichTextUploadingField
6 |
7 |
8 | class PublishedArticlesManager(models.Manager):
9 | def get_queryset(self):
10 | return super().get_queryset().filter(status='publish')
11 |
12 | class Article(models.Model):
13 | STATUS = (
14 | ('draft', 'Draft'),
15 | ('publish', 'Publish')
16 | )
17 | title = models.CharField(max_length=120)
18 | slug = models.SlugField(max_length=120, unique=True)
19 | writer = models.ForeignKey(User, on_delete=models.CASCADE)
20 | body = RichTextUploadingField()
21 | publish = models.DateTimeField(default=timezone.now)
22 | created = models.DateTimeField(auto_now_add=True)
23 | updated = models.DateTimeField(auto_now=True)
24 | status = models.CharField(max_length=20, choices=STATUS, default='draft')
25 | objects = models.Manager()
26 | published = PublishedArticlesManager()
27 |
28 | def __str__(self):
29 | return self.title
30 |
31 | def get_absolute_url(self):
32 | return reverse('blog:article_detail', args=[self.id, self.slug])
--------------------------------------------------------------------------------
/blog/static/blog/css/style.css:
--------------------------------------------------------------------------------
1 | small {
2 | color: red;
3 | }
--------------------------------------------------------------------------------
/blog/templates/blog/all_articles.html:
--------------------------------------------------------------------------------
1 | {% extends 'base.html' %}
2 |
3 | {% block content %}
4 |
5 |
10 |
11 | {% endblock %}
--------------------------------------------------------------------------------
/blog/templates/blog/article.html:
--------------------------------------------------------------------------------
1 | {% extends 'base.html' %}
2 | {% load static %}
3 |
4 |
5 | {% block custom_tags %}
6 |
7 | {% endblock %}
8 |
9 |
10 | {% block content %}
11 | {{ article.title }}
12 | {{ article.publish|timesince }}
13 | {{ article.body|safe }}
14 | {% endblock %}
--------------------------------------------------------------------------------
/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 |
5 | app_name = 'blog'
6 | urlpatterns = [
7 | path('', views.all_articles, name='all_articles'),
8 | path('//', views.article_detail, name='article_detail'),
9 | ]
--------------------------------------------------------------------------------
/blog/views.py:
--------------------------------------------------------------------------------
1 | from django.shortcuts import render, get_object_or_404
2 | from .models import Article
3 |
4 |
5 | def all_articles(request):
6 | all_articles = Article.published.all()
7 | return render(request, 'blog/all_articles.html', {'all_articles':all_articles})
8 |
9 |
10 | def article_detail(request, id, slug):
11 | article = get_object_or_404(Article, id=id, slug=slug)
12 | return render(request, 'blog/article.html', {'article':article})
--------------------------------------------------------------------------------
/db.sqlite3:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/amirbigg/django-blog/23d6d47dd3e309fa736cd891654a09da18d08427/db.sqlite3
--------------------------------------------------------------------------------
/docker-compose.yml:
--------------------------------------------------------------------------------
1 | version: '3.9'
2 |
3 | services:
4 | app:
5 | build: .
6 | command: sh -c "python manage.py migrate && gunicorn A.wsgi -b 0.0.0.0:8000"
7 | container_name: app
8 | volumes:
9 | - .:/code/
10 | ports:
11 | - "8000:8000"
12 | networks:
13 | - main
14 | restart: always
15 |
16 | nginx:
17 | container_name: nginx
18 | command: nginx -g 'daemon off;'
19 | image: nginx:latest
20 | depends_on:
21 | - app
22 | networks:
23 | - main
24 | ports:
25 | - "80:80"
26 | restart: always
27 | volumes:
28 | - ./nginx.conf:/etc/nginx/nginx.conf
29 |
30 | networks:
31 | main:
--------------------------------------------------------------------------------
/manage.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | """Django's command-line utility for administrative tasks."""
3 | import os
4 | import sys
5 |
6 |
7 | def main():
8 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'A.settings')
9 | try:
10 | from django.core.management import execute_from_command_line
11 | except ImportError as exc:
12 | raise ImportError(
13 | "Couldn't import Django. Are you sure it's installed and "
14 | "available on your PYTHONPATH environment variable? Did you "
15 | "forget to activate a virtual environment?"
16 | ) from exc
17 | execute_from_command_line(sys.argv)
18 |
19 |
20 | if __name__ == '__main__':
21 | main()
22 |
23 |
--------------------------------------------------------------------------------
/media/uploads/2019/12/17/sql-course.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/amirbigg/django-blog/23d6d47dd3e309fa736cd891654a09da18d08427/media/uploads/2019/12/17/sql-course.png
--------------------------------------------------------------------------------
/media/uploads/2019/12/17/sql-course_FVmVYxj.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/amirbigg/django-blog/23d6d47dd3e309fa736cd891654a09da18d08427/media/uploads/2019/12/17/sql-course_FVmVYxj.png
--------------------------------------------------------------------------------
/nginx.conf:
--------------------------------------------------------------------------------
1 | user nginx;
2 | worker_processes 1;
3 | error_log /var/log/nginx/error.log;
4 | pid /var/run/nginx.pid;
5 |
6 |
7 | events {
8 | worker_connections 1024;
9 | }
10 |
11 | http {
12 | include /etc/nginx/mime.types;
13 | default_type application/octet-stream;
14 | access_log /var/log/nginx/access.log;
15 |
16 | upstream app {
17 | server app:8000;
18 | }
19 |
20 | server {
21 | listen 80;
22 | server_name localhost;
23 | charset utf-8;
24 |
25 | location / {
26 | proxy_pass http://app;
27 | }
28 | }
29 | }
--------------------------------------------------------------------------------
/requirements.txt:
--------------------------------------------------------------------------------
1 | asgiref==3.3.4
2 | Django==3.0
3 | django-ckeditor==6.0.0
4 | django-js-asset==1.2.2
5 | pytz==2021.1
6 | sqlparse==0.4.1
7 | gunicorn==20.0.4
8 |
--------------------------------------------------------------------------------
/templates/404.html:
--------------------------------------------------------------------------------
1 | {% extends 'base.html' %}
2 |
3 | {% block content %}
4 | 404 Error
5 | This is page is not available
6 | {% endblock %}
--------------------------------------------------------------------------------
/templates/base.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Blog
6 |
7 | {% block custom_tags %} {% endblock %}
8 |
9 |
10 |
11 |
12 | {% include 'inc/navbar.html' %}
13 |
14 | {% include 'inc/messages.html' %}
15 | {% block content %} {% endblock %}
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/templates/inc/messages.html:
--------------------------------------------------------------------------------
1 | {% if messages %}
2 | {% for message in messages %}
3 | {{ message }}
4 | {% endfor %}
5 | {% endif %}
--------------------------------------------------------------------------------
/templates/inc/navbar.html:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------