본문 바로가기

Python_WEB/Try_Django

[Django]Image Field and Uploading Images

CodingEntrepreneurs Django 강의 정리

forms>

from django import forms

from .models import BlogPost


class BlogPostForm(forms.Form):
    title = forms.CharField()
    slug = forms.SlugField()
    content = forms.CharField(widget=forms.Textarea)


class BlogPostModelForm(forms.ModelForm):
    # title = forms.CharField()

    class Meta:
        model = BlogPost
        fields = ["title", "image", "slug", "content", "publish_date"]

    def clean_title(self, *args, **kwargs):
        # print(dir(self))
        instance = self.instance
        print(instance)
        title = self.cleaned_data.get("title")
        qs = BlogPost.objects.filter(title=title)

        if instance is not None:
            qs = qs.exclude(pk=instance.pk)  # id=instance.id

        if qs.exists():
            raise forms.ValidationError(
                "This title has already been used. Please try again."
            )

        return title

 

form.html>

{% extends "base.html" %}

{% block content %}

{% if title %}
<h1>{{ title }}</h1>
{% endif %}

<form method="POST" action="." enctype="multipart/form-data"> {% csrf_token %}
    {{ form.as_p }}
    <button type="submit">Send</button>
</form>

{% endblock %}

 

list-inline.html>

<div class="col-12 col-md-10 mb-3 mx-auto">
    <div class='card {% if not blog_post.publish_date %} bg-dark text-light {% endif %}'>
        <div class='card-body'>
            {% if blog_post.image %}
            <a href="{{ blog_post.get_absolute_url }}">
                <img src="{{ blog_post.image.url }}" class="card-img-top" />
            </a>
            {% endif %}
            <h5 class="card-title">{{ blog_post.title }}</h5>
            <p class="cart-text">
                <small class="text-muted">{{ blog_post.publish_date }}</small>
                {% if truncate %}
                {{ blog_post.content|linebreaks|truncatewords:30 }}
                {% else %}
                {{ blog_post.content|linebreaks }}
                {% endif %}
            </p>
            {% if not detail %}
            {% if not blog_post.publish_date %} Draft {% endif %}
            <a href="{{ blog_post.get_absolute_url }}">View</a>
            {% endif %}
        </div>
    </div>
</div>

 

views>

from django.contrib.auth.decorators import login_required
from django.contrib.admin.views.decorators import staff_member_required
from django.http import Http404
from django.shortcuts import render, get_object_or_404, redirect

# Create your views here.
from .forms import BlogPostModelForm
from .models import BlogPost

# CRUD

# GET -> Retrieve / List

# POST -> Create / Update / DELETE

# Create Retrieve Update Delete


def blog_post_list_view(request):
    # list out objects
    # could be search
    qs = BlogPost.objects.all().published()  # queryset -> list of python object
    if request.user.is_authenticated:
        my_qs = BlogPost.objects.filter(user=request.user)
        qs = (qs | my_qs).distinct()
    # qs = BlogPost.objects.all()  # queryset -> list of python object
    template_name = "blog/list.html"
    context = {"object_list": qs}
    return render(request, template_name, context)


# @login_required
@staff_member_required
def blog_post_create_view(request):
    # create objects
    # ? use a form
    # request.user -> return something
    form = BlogPostModelForm(request.POST or None, request.FILES or None)
    if form.is_valid():
        obj = form.save(commit=False)
        obj.user = request.user
        obj.save()
        form = BlogPostModelForm()
    template_name = "form.html"
    context = {"form": form}
    return render(request, template_name, context)


def blog_post_detail_view(request, slug):
    # 1 object -> detail view
    obj = get_object_or_404(BlogPost, slug=slug)
    template_name = "blog/detail.html"
    context = {"object": obj}
    return render(request, template_name, context)


@staff_member_required
def blog_post_update_view(request, slug):
    obj = get_object_or_404(BlogPost, slug=slug)
    form = BlogPostModelForm(request.POST or None, instance=obj)
    if form.is_valid():
        form.save()
    template_name = "form.html"
    context = {"title": f"Update {obj.title}", "form": form}
    return render(request, template_name, context)


@staff_member_required
def blog_post_delete_view(request, slug):
    obj = get_object_or_404(BlogPost, slug=slug)
    template_name = "blog/delete.html"
    if request.method == "POST":
        obj.delete()
        return redirect("/blog")
    context = {"object": obj}
    return render(request, template_name, context)

 

settings>

"""
Django settings for try_django project.
Generated by 'django-admin startproject' using Django 3.0.7.
For more information on this file, see
https://docs.djangoproject.com/en/3.0/topics/settings/
For the full list of settings and their values, see
https://docs.djangoproject.com/en/3.0/ref/settings/
"""

import os

# 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/3.0/howto/deployment/checklist/

# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = "b#eg47l(0%=d!3uao3xgs68q)_zz+65d4okbfnxsdk-ig$4n9&"

# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True

ALLOWED_HOSTS = []

LOGIN_URL = "/login"


# Application definition

INSTALLED_APPS = [  # components
    "django.contrib.admin",
    "django.contrib.auth",
    "django.contrib.contenttypes",
    "django.contrib.sessions",
    "django.contrib.messages",
    "django.contrib.staticfiles",
    "blog",  # pluggable
]

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",
]

ROOT_URLCONF = "try_django.urls"

TEMPLATES = [
    {
        "BACKEND": "django.template.backends.django.DjangoTemplates",
        "DIRS": [
            os.path.join(BASE_DIR, "templates")
        ],  # 'D:\Code\Study\Try_DJANGO_TUTORIAL_Ver2.2\templates'
        "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",
            ],
        },
    },
]

WSGI_APPLICATION = "try_django.wsgi.application"


# Database
# https://docs.djangoproject.com/en/3.0/ref/settings/#databases

DATABASES = {
    "default": {
        "ENGINE": "django.db.backends.sqlite3",
        "NAME": os.path.join(BASE_DIR, "db.sqlite3"),
    }
}


# Password validation
# https://docs.djangoproject.com/en/3.0/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/3.0/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/3.0/howto/static-files/

STATIC_URL = "/static/"

LOCAL_STATIC_CDN_PATH = os.path.join(BASE_DIR, "static_cdn_test")

STATIC_ROOT = os.path.join(LOCAL_STATIC_CDN_PATH, "static")  # live cdn AWS S3
STATICFILES_DIRS = [os.path.join(BASE_DIR, "staticfiles")]

MEDIA_ROOT = os.path.join(LOCAL_STATIC_CDN_PATH, "media")
MEDIA_URL = "/media/"  # django-storages