前提・実現したいこと
DjangoでSNSアプリを作成しており、画像アップロードの動作を組み込もうとしています。
基本的なSNS動作は書籍のサンプルコードを使用しており、そこから自分なりに機能を追加しています。
使用している書籍:Python Django超入門 著者:掌田 氏 (SNSサンプル:第5章~)
実現したい動作としては
① POST(投稿)ページから画像を添付
② POST!ボタンで送信した際、画像のURL情報(もしくは画像タイトル)を取得
③ Messageモデル(DB)に画像情報を保存
④ プロジェクトフォルダの/media/フォルダに画像を保存
⑤ SNSトップページに /media/画像タイトル で画像を出力
のような動作です。途中動作が前後する可能性もありますが、結果出力できれば良いと思っています。
発生している問題・エラーメッセージ
POSTページに表示している画像参照フォームは
image = forms.ImageField()
送信後の読み取りは
image = request.POST['image']
としています。
しかしこの状態では、入力された画像パスがそのまま取得されてしまい
DBの管理画面で確認すると、/media/D:/----- のような結果になってしまいます。
また、/media/フォルダに画像が保存できません。
ところが、DBにログインし管理画面から画像添付を行うと
/media/画像名 と自動的に画像名のみ出力され
/media/フォルダに画像が保存されます。
なんとかして、この2つの状況を足し合わせたいのですが・・・。
該当のソースコード
#settings.py(追記分) #画像保存場所の指定 MEDIA_URL = '/media/' MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
#urls.py(追記分) #画面に画像を表示する為のもの urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
#models.py from django.db import models from django.contrib.auth.models import User # Messageクラス class Message(models.Model): owner = models.ForeignKey(User, on_delete=models.CASCADE, \ related_name='message_owner') group = models.ForeignKey('Group', on_delete=models.CASCADE) content = models.TextField(max_length=1000) share_id = models.IntegerField(default=-1) good_count = models.IntegerField(default=0) share_count = models.IntegerField(default=0) pub_date = models.DateTimeField(auto_now_add=True) image = models.ImageField(blank=True, null=True) #追加箇所 #コメントとユーザー名を出力する def __str__(self): #__str__は、インスタンスを文字列に変換する return str(self.content) + ' (' + str(self.owner) + ')' #シェアした元メッセージを出力する def get_share(self): return Message.objects.get(id=self.share_id) #日時の古い順に並べ替える class Meta: ordering = ('-pub_date',)
#forms.py from django import forms from.models import Message,Group,Friend,Good from django.contrib.auth.models import User # 投稿フォーム class PostForm(forms.Form): #メッセージ入力欄(Textarea=広い入力ボックス) content = forms.CharField(max_length=500, \ widget=forms.Textarea) image = forms.ImageField() #追加箇所 def __init__(self, user, *args, **kwargs): super(PostForm, self).__init__(*args, **kwargs) #publicに自身のユーザー名を取得 #自身のユーザーがオーナーのグループをリスト内包表記でタプル取得 public = User.objects.filter(username='public').first() self.fields['groups'] = forms.ChoiceField( choices=[('-','-')] + [(item.title, item.title) \ for item in Group.objects. \ filter(owner__in=[user,public])], )
#views.py from django.shortcuts import render from django.shortcuts import redirect from django.contrib.auth.models import User from django.contrib import messages from .models import Message,Friend,Group,Good from .forms import GroupCheckForm,GroupSelectForm,\ SearchForm,FriendsForm,CreateGroupForm,PostForm from django.db.models import Q from django.contrib.auth.decorators import login_required #from django.urls import reverse_lazy #from django.views import generic #from .forms import UploadModelForm #from .models import UploadFile # メッセージのポスト処理 【Post!ボタン】 @login_required(login_url='/admin/login/') def post(request): # POST送信の処理 if request.method == 'POST': # 送信内容の取得(グループ名・コンテンツ(メッセージ)) gr_name = request.POST['groups'] content = request.POST['content'] image = request.POST['image'] #追加箇所 # Groupの取得(Noneの場合はpublicグループ) group = Group.objects.filter(owner=request.user) \ .filter(title=gr_name).first() if group == None: (pub_user, group) = get_public() # Messageのインスタンスを作成し設定して保存 msg = Message() msg.owner = request.user msg.group = group msg.content = content msg.image = image #追加箇所 msg.save() # メッセージを設定 messages.success(request, '新しいメッセージを投稿しました!') return redirect(to='/sns')
処理が重く、全て貼ることが出来ませんでした。
その他公開が必要なプログラム部分があれば教えてください。
試したこと
上記の状態です。
アップロードについては下記を参考にしています。
https://narito.ninja/blog/detail/92/
http://sr2460.hatenablog.com/entry/2019/02/14/213617?_ga=2.147647986.490112225.1550722323-1409412485.1430535027
補足情報(FW/ツールのバージョンなど)
ここにより詳細な情報を記載してください。
回答1件
あなたの回答
tips
プレビュー