SNSなどの動画やメッセージを投稿するときにユーザー情報をあらかじめ入力して誰が投稿したのかをわかるようにしました。
Table of Contents
環境
- Django3.1
- python 3.7.3
- Visual Studio Code
省略
- ユーザーの作成、登録方法 ユーザーページの表示
- django インストール方法 アプリケーションの作成
省略された部分も気になる方はこちらのサイトを見ることをお勧めします。かなりこの人のブログをベースになっています。
コード解説
Models.py
from django.db import models
from django.conf import settings
from django.conf import settings
from django.utils import timezone
import random string
def random_url():
chars = '0123456789abcdefghijkmnopqrstuvwxzyABCDEFGHIJKLMNOPQRSTUVWXYZ'
url = ''.join(random.choice(chars)for i in range(16))
return url
class Post(models. Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL,on_delete=models.CASCADE)
title = models.charField(_('タイトル')max_length=150)
post = models.TextField(_('内容'))
url = models.UrlField(_('URL')blank = True)
slug = models.SlugField(unique=True, default=random_url )
create_day = models.DateTimeField(_('作成日',default=timezone.now)
def get_absolute_url(self):
return reversed('series', kwargs={'slug': self.slug})
def __str__(self):
return self.title
models.ForeignKey の機能を使ってユーザー情報を結びつけます。settings.AUTH_USER_MODELと指定していますがsettings.py のファイル内でuserを指定しています。公式ドキュメントでは推奨していませんが、(User 〜 )でも可能です。on_delete=models.CASCADE でユーザーを削除した時に投稿したメッセージも一緒に削除するように指示ができます。
UrlField 内にあるblank=Trueは、URLを入力しなくてもOKということを指示します。
models.SlugField(unique=True, default=random_url)
このフィールドではrandom_urlで0から大文字Zまでの60文字をランダムに16個選んだものをUrlとして指定しています。unique =Trueで被ってしまったら作れないように指示しています。1/60の16乗(60×60を15回繰り返す少なくても100京以上)の確率ですが念のために被らないようにします。
def get_absolute_url(self):return reversed(‘series’, kwargs={‘slug’: self.slug})
でUrlの指定を行います。
forms.py
from django import forms
from
class PostForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs) for field in self.fields.values():
field.widget.attrs['class'] = 'form-control'
class Meta:
model = Post
fields = ('title','post',)
ここはモデルから参照してフォームからどこの項目に入れるのかを指示する画面になります。ここでは、model Postからタイトルと本文を入力できるようにしました。
Views.py
from .form import PostForm
from .mixins import OnlyYouMixin
from django.views import generic
class Top(generic.ListView):
"""公開記事の一覧を表示する。"""
model = Movie
template_name = 'top.html'
paginate_by = 10
class PostUpload(OnlyYouMixin, generic.CreateView):
template_name = 'app/post_upload.html'
form_class = PostForm
def form_valid(self,form):
form.instance.user = self.request.user
return super().form_valid(form)
def get_success_url(self):
return resolve_url('APP:Top')
class Post(generic.DetailView):
template_name = 'app/post.html
def form_valid(self, form): を呼び出し、form.instance.user = self.request.user を使うことでModel Post内にあるUserの項目から現在ログインしているユーザーを代入することができます。 完了したらTop画面に戻るように指示します。
ちなみに OnlyYouMixin では、ログインしたユーザーしか入れないようにしています。
urls.py
アプリフォルダの中にurls.py を新たに作り以下のようにします。
from django.urls import path,include
from django.contrib.auth import admin
from . models import User
from . import views
path('', views.Top.as_view(), name='TOP'),
#投稿するもの
path('user<int:pk>/upload',views.PostUpload.as_view(),name='PostUpload'),
#投稿もの
path('<slug:slug>',views.Post.as_view(),name = 'post'
user<int:pk>でユーザー情報の取得後USERページから投稿画面に移行する
post_upload.html
{% block content %}
{% load static %}
{% for field in form %}
<div class="form-group">
<label for="{{ field.id_for_label }}">{{ field.label_tag }}</label>
{{ field.value }}
</div>
{% endfor %}
<form enctype="multipart/form-data" action="{% url 'register:user_data_input' %}" method="POST">
<button type="submit" class="btn btn-primary btn-lg">戻る</button>
{% for field in form %}{{ field.as_hidden }}{% endfor %}
{% csrf_token %}
</form>
<hr>
<form action="{% url 'register:user_data_create' %}" method="POST">
<button type="submit" class="btn btn-primary btn-lg">送信</button>
{% for field in form %}{{ field.as_hidden }}{% endfor %}
{% csrf_token %}
</form>
{% endblock %}
これで投稿画面の設定は完了、ターミナルで”python manage.py runserver “を入力して動かせたら勝ち!
画像は開いた時に投稿します。