質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Django

DjangoはPythonで書かれた、オープンソースウェブアプリケーションのフレームワークです。複雑なデータベースを扱うウェブサイトを開発する際に必要な労力を減らす為にデザインされました。

Q&A

解決済

1回答

1638閲覧

Django: ImportError: cannot import name 'PostAddForm' from 'XX.forms'のエラー

tetsuk

総合スコア6

Django

DjangoはPythonで書かれた、オープンソースウェブアプリケーションのフレームワークです。複雑なデータベースを扱うウェブサイトを開発する際に必要な労力を減らす為にデザインされました。

0グッド

0クリップ

投稿2020/12/01 15:42

編集2020/12/01 15:49

前提・実現したいこと

Djangoでブログのアプリを作っており、ログイン・ユーザーが自分のブログページにのみ投稿・編集でき、
他ユーザーの投稿については他ユーザーのページで閲覧のみできるような形にしようと考えています。

発生している問題・エラーメッセージ

カスタムユーザーモデルを作成し、

python manage.py makemigrations

をしようとしたところ、下記のエラーが発生しました。

File "/Users/user/Documents/django_work/reportproject/reportpost/urls.py", line 4, in <module> from . import views File "/Users/user/Documents/django_work/reportproject/reportpost/views.py", line 7, in <module> from .forms import PostAddForm ImportError: cannot import name 'PostAddForm' from 'reportpost.forms' (/Users/user/Documents/django_work/reportproject/reportpost/forms.py)

最初にブログのCRUDの機能を実装し、その後、デフォルトユーザーモデルで、ユーザー登録等の機能も実装の上で、カスタムユーザーモデルに変更しようとしたところ、エラーが発生しました。
調べたところデフォルトユーザーでのmigrateをした後でカスタムユーザーモデルに変更するのは煩雑で難易度が高そうだったため、
プロジェクトの設定から全部やり直した上で、makemigrationsを試みている、という経緯があります。

該当のソースコード

アプリディレクトリは、reportpostaccountsの2つで、設定ディレクトリ(プロジェクトパッケージ)はconfigという名前に設定しています。

reportproject/reportpost.views.py

python

1from django.contrib.auth.decorators import login_required 2from django.shortcuts import render, get_object_or_404, redirect 3from django.views.decorators.http import require_POST 4 5from .models import Post 6from .forms import PostAddForm 7 8from accounts.models import CustomUser 9 10 11def index(request): 12 """全ユーザーの一覧表示""" 13 return render(request, 'index.html') 14 15def list(request, user_id): 16 """ユーザーごとの一覧表示""" 17 user = get_object_or_404(CustomUser, id=user_id) 18 posts = user.post_set.all().order_by('-created_at') 19 return render(request, 'list.html', {'user': user, 'posts': posts}) 20 21def detail(request, post_id): 22 """ユーザー個別記事の詳細表示""" 23 post = get_object_or_404(Post, id=post_id) 24 return render(request, 'detail.html', {'post': post}) 25 26@login_required 27def add(request): 28 """記事の追加""" 29 if request.method == "POST": 30 form = PostAddForm(request.POST, request.FILES) 31 if form.is_valid(): 32 post = form.save(commit=False) 33 post.user = request.user 34 post.save() 35 return redirect('reportpost:list', user_id=user.id) 36 else: 37 form = PostAddForm() 38 return render(request, 'add.html', {'form': form}) 39 40@login_required 41def edit(request, post_id): 42 """記事の編集""" 43 post = get_object_or_404(Post, id=post_id) 44 if request.method == "POST": 45 form = PostAddForm(request.POST, request.FILES, instance=post) 46 if form.is_valid(): 47 post = form.save(commit=False) 48 post.user = request.user 49 post.save() 50 return redirect('reportpost:detail', post_id=post.id) 51 else: 52 form = PostAddForm(instance=post) 53 return render(request, 'edit.html', {'form': form, 'post':post}) 54 55@login_required 56@require_POST 57def delete(request, post_id): 58 """記事の削除""" 59 post = get_object_or_404(Post, id=post_id) 60 post.delete() 61 return redirect('reportpost:list', user_id=user.id)

reportproject/reportpost/models.py

python

1from django.db import models 2from django.utils import timezone 3# from django.contrib.auth.models import User 4 5from accounts.models import CustomUser 6 7 8class Post(models.Model): 9 title = models.CharField('タイトル', max_length=35) 10 text = models.TextField('本文') 11 image = models.ImageField('画像', upload_to = 'images', blank=True) 12 created_at = models.DateTimeField('投稿日', default=timezone.now) 13 user = models.ForeignKey(CustomUser, on_delete=models.PROTECT) 14 15 def __str__(self): 16 return self.title

reportproject/reportpost/forms.py

python

1from django import forms 2from .models import Post 3from django.forms import ModelForm 4 5class PostAddForm(forms.ModelForm): 6 title = forms.CharField(label='タイトル', max_length=35, widget=forms.TextInput( 7 attrs={'placeholder':'タイトル', 'class':'class_name'})) 8 text = forms.CharField(label='本文', widget=forms.Textarea(attrs={'rows':20, 'placeholder':'本文'})) 9 class Meta: 10 model = Post 11 fields = ['title', 'text', 'image']

reportproject/reportpost/urls.py

python

1from django.contrib import admin 2from django.urls import path 3 4from . import views 5 6app_name = 'reportpost' 7urlpatterns = [ 8 path('', views.index, name='index'), 9 path('user/<int:user_id>/', views.list, name='list'), 10 path('detail/<int:post_id>/', views.detail, name='detail'), 11 path('add/', views.add, name='add'), 12 path('edit/<int:post_id>/', views.edit, name='edit'), 13 path('delete/<int:post_id>/', views.delete, name='delete'), 14]

reportproject/accounts/models.py

python

1from django.contrib.auth.models import AbstractUser 2from django.db import models 3 4 5class Department(models.Model): 6 dpt = models.CharField('担当', max_length=20) 7 def __str__(self): 8 return self.dpt 9 10class CustomUser(AbstractUser): 11 class Meta: 12 db_table = 'custom_user' 13 14 dpt = models.ForeignKey(Department, verbose_name='担当', blank=True, null=True, on_delete=models.PROTECT) 15

reportproject/accounts/forms.py

python

1from django import forms 2from django.contrib.auth.forms import UserCreationForm 3# from django.contrib.auth.models import User 4 5from .models import CustomUser 6 7class SignupForm(UserCreationForm): 8 class Meta: 9 model = CustomUser 10 fields = ['username', 'email', 'dpt', 'password1', 'password2']

reportproject/accounts/views.py

python

1from django.contrib.auth import login 2from django.contrib.auth.decorators import login_required 3from django.contrib.auth.models import User 4from django.shortcuts import render, get_object_or_404, redirect 5from django.urls import reverse_lazy 6from django.views.generic import CreateView 7 8from .forms import SignupForm 9 10 11class SignupView(CreateView): 12 template_name = 'signup.html' 13 form_class = SignupForm 14 success_url = reverse_lazy('reportpost:index') 15 16 def form_valid(self, form): 17 # self.objectにsave()されたユーザーオブジェクトが格納される 18 valid = super().form_valid(form) 19 login(self.request, self.object) 20 return valid 21 22@login_required 23def edit(request, user_id): 24 user = get_object_or_404(User, id=user_id) 25 if request.method == "POST": 26 form = SignupForm(request.POST, instance=request.user) 27 if form.is_valid(): 28 form.save() 29 return redirect('reportpost:list', user_id=user.id) 30 else: 31 form = SignupForm(instance=user) 32 return render(request, 'accounts/edit.html', {'form': form, 'user': user})

reportproject/accounts/urls.py

python

1from django.contrib import admin 2from django.urls import path 3from django.contrib.auth import views as auth_views 4from . import views 5 6app_name = 'accounts' 7urlpatterns = [ 8 path('login/', auth_views.LoginView.as_view(template_name='login.html'), name='login'), 9 path('logout/', auth_views.LogoutView.as_view(), name='logout'), 10 path('signup/', views.SignupView.as_view(), name='signup'), 11 path('user/edit/<int:user_id>', views.edit, name='edit'), 12]

reportproject/config/urls.py

python

1from django.contrib import admin 2from django.urls import path, include 3from django.conf import settings 4from django.conf.urls.static import static 5 6urlpatterns = [ 7 path('admin/', admin.site.urls), 8 path('', include('accounts.urls')), 9 path('', include('reportpost.urls')), 10 path('accounts/', include('allauth.urls')), 11] 12 13urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) 14 15urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)

補足情報(FW/ツールのバージョンなど)

conda 4.9.2
django 3.1.2
python 3.9.0

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

自己解決

reportproject/reportpost/forms.pyPostAddFormクラスの

fields = ['title', 'text', 'image']

fields = ['title', 'text', 'image', 'user']

に変えてmakemigrationsしたところ、エラーが発生せずに完了しました。

デフォルトユーザークラスで実装していた時は、ここに'user'は必須ではなかったような記憶なので、
釈然とはしないのですが、一先ずエラーは解消されました。

投稿2020/12/01 17:01

tetsuk

総合スコア6

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

FKM

2020/12/02 00:43

自己解決なら自己解決にしておいた方が後々、別の利用者が助かりますのでご協力お願い致します。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問