Image Upload Site

Python

pj/app/views.py

from django.contrib import messages

from django.contrib.auth import authenticate

from django.contrib.auth import login

from django.contrib.auth.decorators import login_required

from django.contrib.auth.models import User

from django.contrib.auth.forms import UserCreationForm

@require_POST

def delete(request, pk):

photo = get_object_or_404(Photo, pk=pk, user=request.user)

photo.delete()

return redirect(“app:user”, request.user.id)

@login_required ③

def new(request):

if request.method == “POST”:

form = PhotoForm(request.POST, request.FILES)

if form.is_valid():

photo = form.save(commit=False) ④

photo.user = request.user

photo.save()

messages.success(request, “投稿完了”)

return redirect(“app:user”, pk=request.user.pk)

else:

form = PhotoForm()

return render(request, “app/new.html”, {“form”:form})

def category(request, category):

category = get_object_or_404(Category, title=category) ⑤

photos = Photo.objects.filter(category=category).order_by(“-created_at”)

return render(request, “app/index.html”, {“photos”:photos, “category”:category})

def user(request, pk):

user = get_object_or_404(User, pk=pk)

photos = user.photo_set.all().order_by(“-created_at”)

return render(request, ‘app/user.html’, {“user”:user, “photos”: photos})

def signup(request):

if request.method == “POST”:

form = UserCreationForm(request.POST) ①

if form.is_valid():

form.save()

input_username = form.cleaned_data[“username”]

input_password = form.cleaned_data[“password1”]

new_user = authenticate( ②

username=input_username,

password=input_password,

)

if new_user is not None:

login(request, new_user)

return redirect(“app:user”, pk=new_user.pk)

else:

form = UserCreationForm()

return render(request, “app/signup.html”, {“form”:form})

—————————————-

①UserCreationFormは入力された値に対して、次の3点をチェック

・password1とpassword2の入力値が一致しているか

・パスワードとしてふさわしい値が入力されているか

・同名のユーザが存在していないか

②authenticateはusernameとpasswordの組み合わせが正しいか確認する関数

正しければnew_userにデータが入力されてlogin()され、users_detail.htmlにリダイレクト

③login_requireはデコレータと呼ばれる機能

ユーザーがログインしていればnew関数をそのまま実行

していなければ、new関数を実行せずにsettings.pyで設定したLOGIN_URLにリダイレクト

④form.save(commit=False)だとデータベースには保存しない

⑤titleがURLの文字列と一致するCategoryインスタンスを取得し、

取得した変数categoryのPhoto一覧を取得

pj/app/models.py

from django.db import models

from django.contrib.auth.models import User

class Category(models.Model): ④

title = models.CharField(max_length=20)

def __str__(self):

return self.title

class Photo(models.Model):

title = models.CharField(max_length=50)

comment = models.TextField(blank=True)

image = models.ImageField(upload_to=”photos”) ①

     created_at = models.DateTimeField(auto_now=True)

category = models.ForeignKey(Category, on_delete=models.PROTECT) ②

user = models.ForeignKey(User, on_delete=models.CASCADE) ②

def __str__(self):

return self.title

———————————–

①ImageFieldを使う場合はcd pjでpip install Pillowが必要

また、upload_to=”photos”で、pj/media/photosにアップロード

②on_delete=models.PROTECTとすると、Userインスタンスを削除しても紐づいた投稿は削除されない

on_delete=models.CASCADEとすると、Userインスタンスが削除されたとき紐づいた投稿も削除

④Userモデルと同じようにCategoryモデルを作成

titleに風景や動物といったカテゴリを格納

pj/app/templates/app/base.html

{% load static %}

<!DOCTYPE html>

<html>

<head>

<title></title>

<link rel=”stylesheet” type=”text/css” href=”{% static ‘css/style.css’ %}”>

</head>

<body>

<header>

<a href=”{% url ‘app:index’ %}”>HOME</a>

<a href=”{% url ‘app:new’ %}”>NEW</a>

{% if request.user.is_authenticated %} ①

<a href=”{% url ‘app:user’ request.user.id  %}”>USER</a>

<a href=”{% url ‘app:logout’ %}”>LOGOUT</a>

{% else %}

<a href=”{% url ‘app:login’ %}”>LOGIN</a>

{% endif %}

</header>

<main>

{% for message in messages %}

{{ message }}

{% endfor %}

{% block content %}{% endblock %} 

</main>

</body>

</html>

pj/app/templates/app/index.html

{% extends “app/base.html” %}

{% block content %}

{% if category %}

{{ category.title }}の検索結果

{% endif %}

{% for photo in photos %}

<a href=”{% url ‘app:detail’ photo.id %}”><img src=”{{ photo.image.url }}”></a>

<a href=””>{{ photo.category }}</a>

<a href=”{% url ‘app:user’ photo.user.id %}”>@{{ photo.user }}</a>

{% endfor %}

{% endblock %}

pj/app/templates/app/detail.html

{% extends “app/base.html” %}

{% block content %}

<img src=”{{ photo.image.url }}”>

<a href=”{% url ‘app:detail’ photo.user.id %}”>@{{ photo.user }}</a>

{{ photo.title }}

{{ photo.comment }}

{% if request.user == photo.user %}

<form method=”POST” action=”{% url ‘app:delete’ photo.id %}”>

{% csrf_token %}

<button type=”submit”>DELETE</button>

</form>

{% endif %} 

{% endblock %}

pj/app/templates/app/user.html

{% extends “app/base.html” %}

{% block content %}

<h2>@{{ user.username }}</h2>

{% if user.is_superuser %}<p>管理者</p>

{% else %}<p>一般ユーザー</p>

{% endif %}

{% if photos.count != 0 %}{{ photos.count }}件

{% else %}@{{ user.username }}さんはまだ投稿していません。

{% endif %}

{% for photo in photos %}

<a href=”{% url ‘app:detail’ photo.id %}”><img src=”{{ photo.image.url }}”></a>

<a href=””>{{ photo.category }}</a>

<a href=”{% url ‘app:user’ photo.user.id %}”>@{{ photo.user }}</a>

{% endfor %}

{% endblock %}

BACK