i have deployed my django app in heroku, postgresql as db and for storing images i haved used amazon S3 storage, the problem what i am facing is, for creating a blog post i have used ckeditor, so user can input images along with the content text for creating a post.
after creating a post it looks like below
when right clicked on post image and open link in new tab is selected, below is the url of S3 for the image uploaded
after sometime images are deleted, only text content remains
models.py
class Post(models.Model):
title = models.CharField(max_length=100)
category = models.ForeignKey(Category, on_delete=models.CASCADE ,blank=True)
content = RichTextUploadingField()
date_posted = models.DateTimeField(default=timezone.now)
author = models.ForeignKey(User, on_delete=models.CASCADE)
thumbnail = models.ImageField(default='default_content.jpg', upload_to='content_pic')
likes = models.ManyToManyField(User, related_name="likes", blank=True)
def __str__(self):
return self.title
views.py
from django.shortcuts import render,get_object_or_404,redirect
from .models import Post,Comment,Category,No_Of_Views,carousel_images_messages,about_page_details
from django.views.generic import ListView,DetailView,CreateView,UpdateView,DeleteView
from django.contrib.auth.mixins import LoginRequiredMixin,UserPassesTestMixin
from django.contrib.auth.models import User
from .forms import CommentForm
from django.template.loader import render_to_string
from django.http import JsonResponse
from django.db.models import Count
from django.db.models import Q
from django.core.mail import send_mail
from django.contrib import messages
# Create your views here.
class PostDetailView(DetailView):
model = Post
context_object_name = 'post'
def get_queryset(self):
return Post.objects.filter(pk=self.kwargs.get('pk')).order_by("-date_posted")
def get_context_data(self, **kwargs):
# no of views
no_of_views = No_Of_Views.objects.filter(post=self.kwargs.get('pk')).exists()
#RealEstateListing.objects.filter(slug_url=slug).exists()
if no_of_views:
no_of_views_count = No_Of_Views.objects.get(post=self.kwargs.get('pk'))
print(no_of_views_count.username)
print(self.request.user)
print(no_of_views_count.views_count)
if no_of_views_count.username != self.request.user.username:
no_of_views_save = int(no_of_views_count.views_count) + 1
no_of_views_count.views_count = no_of_views_save
no_of_views_count.save()
else:
no_of_views_save = no_of_views_count.views_count
else:
post_title = Post.objects.get(pk=self.kwargs.get('pk'))
print(post_title.title)
no_of_views_save = 0
no_of_views_for_post = No_Of_Views(post=self.kwargs.get('pk'),post_title=post_title.title,username=post_title.author,views_count=no_of_views_save)
no_of_views_for_post.save()
## ends here
context = super().get_context_data(**kwargs)
post = Post.objects.filter(pk=self.kwargs.get('pk')).order_by("-date_posted")
context['comments'] = Comment.objects.filter(post=post[0],reply=None).order_by("-id")
context['comment_form'] = CommentForm()
is_liked = False
if post[0].likes.filter(id=self.request.user.id).exists():
is_liked = True
similar_post_pk = Post.objects.filter(pk=self.kwargs.get('pk')).order_by("-date_posted")
similar_post_pk = similar_post_pk[0]
similar_post = Post.objects.filter(category__category__iexact=similar_post_pk.category.category).exclude(pk=self.kwargs.get('pk')).order_by("-date_posted")[:3]
if len(similar_post) == 0:
similar_post = Post.objects.all().exclude(pk=self.kwargs.get('pk')).order_by("-date_posted")[:3]
context['is_liked'] = is_liked
context['similar_posts'] = similar_post
context['views'] = int(no_of_views_save)
response = common_info()
context['categories'] = response["categories"]
context['popular_posts'] = response["popular_post"]
title = (post[0]).title
context['title'] = title
#context['total_likes'] = post.total_likes()
return context
def post(self, request, *args, **kwargs):
post = Post.objects.filter(pk=self.kwargs.get('pk')).order_by("-date_posted")
comment_form = CommentForm(request.POST)
if comment_form.is_valid():
content = comment_form.cleaned_data["content"]
reply_id = self.request.POST.get("comment_id")
comment_qs = None
if reply_id:
comment_qs = Comment.objects.get(id=reply_id)
comment_form = Comment.objects.create(post=post[0],user=self.request.user,content=content, reply=comment_qs)
comment_form.save()
return redirect("post-detail",pk=self.kwargs.get('pk'))
class PostCreateView(LoginRequiredMixin,CreateView):
model = Post
fields = ["title","category","content","thumbnail"]
def form_valid(self, form):
form.instance.author = self.request.user
return super().form_valid(form)
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
response = common_info()
context['categories'] = response["categories"]
context['title'] = 'Create Blog'
return context
settings.py
import os
import django_heroku
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/2.1/howto/deployment/checklist/
# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = os.environ.get('SECRET_KEY')
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True
ALLOWED_HOSTS = ["localhost"]
# Application definition
INSTALLED_APPS = [
'users.apps.UsersConfig',
'blog.apps.BlogConfig',
'crispy_forms',
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'storages',
'django.contrib.humanize',
'ckeditor',
'ckeditor_uploader',
'social_django',
#'sslserver'
]
CKEDITOR_UPLOAD_PATH = 'uploads/'
CKEDITOR_CONFIGS = {
'awesome_ckeditor': {
'toolbar': 'Basic',
'width':'auto'
},
'default': {
'toolbar': 'full',
'width':'auto'
},
}
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
'social_django.middleware.SocialAuthExceptionMiddleware', # added for social login
]
ROOT_URLCONF = 'young_minds.urls'
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
'social_django.context_processors.backends', # added for social login
'social_django.context_processors.login_redirect', # added for social login
],
},
},
]
# for social login
AUTHENTICATION_BACKENDS = (
'social_core.backends.open_id.OpenIdAuth', # for Google authentication
'social_core.backends.google.GoogleOpenId', # for Google authentication
'social_core.backends.google.GoogleOAuth2', # for Google authentication
'social_core.backends.github.GithubOAuth2',
'social_core.backends.twitter.TwitterOAuth',
'social_core.backends.facebook.FacebookOAuth2',
'django.contrib.auth.backends.ModelBackend',
)
SOCIAL_AUTH_GITHUB_KEY = os.environ.get('SOCIAL_AUTH_GITHUB_KEY')
SOCIAL_AUTH_GITHUB_SECRET = os.environ.get('SOCIAL_AUTH_GITHUB_SECRET')
SOCIAL_AUTH_FACEBOOK_KEY = os.environ.get('SOCIAL_AUTH_FACEBOOK_KEY') # App ID
SOCIAL_AUTH_FACEBOOK_SECRET = os.environ.get('SOCIAL_AUTH_FACEBOOK_SECRET') # App Secret
SOCIAL_AUTH_GOOGLE_OAUTH2_KEY = os.environ.get('SOCIAL_AUTH_GOOGLE_OAUTH2_KEY')
SOCIAL_AUTH_GOOGLE_OAUTH2_SECRET = os.environ.get('SOCIAL_AUTH_GOOGLE_OAUTH2_SECRET')
WSGI_APPLICATION = 'young_minds.wsgi.application'
# Database
# https://docs.djangoproject.com/en/2.1/ref/settings/#databases
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': 'mydatabase',
}
}
# Password validation
# https://docs.djangoproject.com/en/2.1/ref/settings/#auth-password-validators
AUTH_PASSWORD_VALIDATORS = [
{
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
},
]
# Internationalization
# https://docs.djangoproject.com/en/2.1/topics/i18n/
LANGUAGE_CODE = 'en-us'
TIME_ZONE = 'UTC'
USE_I18N = True
USE_L10N = True
USE_TZ = True
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/2.1/howto/static-files/
STATIC_ROOT = os.path.join(BASE_DIR, "staticfiles")
STATIC_URL = '/static/'
MEDIA_URL = "/media/"
MEDIA_ROOT = os.path.join(os.path.dirname(BASE_DIR), "media")
LOGIN_REDIRECT_URL = 'blog-home'
LOGIN_URL = 'login'
LOGIN_REDIRECT_URL = 'blog-home'
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
EMAIL_HOST = 'smtp.gmail.com'
EMAIL_PORT = 587
EMAIL_USE_TLS = True
EMAIL_HOST_USER = os.environ.get('EMAIL_HOST_USER')
EMAIL_HOST_PASSWORD = os.environ.get('EMAIL_HOST_PASSWORD')
AWS_ACCESS_KEY_ID = os.environ.get('AWS_ACCESS_KEY_ID')
AWS_SECRET_ACCESS_KEY = os.environ.get('AWS_SECRET_ACCESS_KEY')
AWS_STORAGE_BUCKET_NAME = os.environ.get('AWS_STORAGE_BUCKET_NAME')
AWS_S3_URL = AWS_STORAGE_BUCKET_NAME + '.s3.amazonaws.com'
#AWS_S3_URL = '%s.s3.amazonaws.com' % AWS_STORAGE_BUCKET_NAME
AWS_S3_REGION_NAME = "us-west-2"
AWS_S3_FILE_OVERWRITE = False
AWS_DEFAULT_ACL = None
DEFAULT_FILE_STORAGE = "storages.backends.s3boto3.S3Boto3Storage"
#STATICFILES_STORAGE = 'storages.backends.s3boto3.S3Boto3Storage'
django_heroku.settings(locals())
i have used S3 for thumbnail of the post which is direct image field , this doesn't get deleted, only problem is the post images which i embedded with content using ckeditor gets deleted after sometime of uploading .
any extra information required , i will update it.
thanks in advance!