├── .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 | 6 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 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 |
5 | {% csrf_token %} 6 | {{ form.as_p }} 7 | 8 |
9 | 10 | {% endblock %} -------------------------------------------------------------------------------- /accounts/templates/accounts/register.html: -------------------------------------------------------------------------------- 1 | {% extends 'base.html' %} 2 | 3 | {% block content %} 4 |
5 | {% csrf_token %} 6 | {{ form.as_p }} 7 | 8 |
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 |
6 | {% for article in all_articles %} 7 | {{ article.title }} 8 | {% endfor %} 9 |
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 | --------------------------------------------------------------------------------