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

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

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

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

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

1回答

1929閲覧

djangoで任意のユーザー名をurlに設定したプロフィール情報ページに遷移させたい

cetus

総合スコア3

Django

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

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2020/12/10 03:59

前提・実現したいこと

Djangoを勉強し始めて1か月程度の者です。

djangoでurl ~~/profile/<ユーザー名>のようにあるアカウントのユーザー名をurlに指定してユーザーのプロフィール情報を表示したいのですが、プロフィール情報のリンク先に飛ばず表示しているページが再度表示されてしまうという現象が発生しています。

以前はリンク先には遷移することができ、Field 'id' expected a number but got ~~(~~はユーザー名)というようなエラーが出ていたのですがいろいろいじっているうちにエラーも表示されなくなり上記のような状態になりました。

なので、直接urlを打ち込む、もしくは管理サイトからサイト上で表示をクリックして該当ページに進んだところ、Generic detail view ProfileDetailView must be called with either an object pk or a slug in the URLconf.というエラーが表示されるようになりました。

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

AttributeError at /profile/ユーザー名/ Generic detail view ProfileDetailView must be called with either an object pk or a slug in the URLconf. Request Method: GET Request URL: http://127.0.0.1:8000/profile/qq/ Django Version: 3.0.3 Exception Type: AttributeError Exception Value: Generic detail view ProfileDetailView must be called with either an object pk or a slug in the URLconf. Python Version: 3.8.3

該当のソースコード

models.py

from django.db import models from django.contrib.auth.models import AbstractBaseUser, PermissionsMixin from django.contrib.auth.validators import UnicodeUsernameValidator from django.utils import timezone from django.utils.translation import gettext_lazy as _ from django.core.mail import send_mail from django.contrib.auth.base_user import BaseUserManager from django.urls import reverse class UserManager(BaseUserManager): ... class User(AbstractBaseUser, PermissionsMixin): """ An abstract base class implementing a fully featured User model with admin-compliant permissions. Username and password are required. Other fields are optional. """ username_validator = UnicodeUsernameValidator() username = models.CharField( _('username'), max_length=150, unique=True, help_text=_('Required. 150 characters or fewer. Letters, digits and @/./+/-/_ only.'), validators=[username_validator], error_messages={ 'unique': _("A user with that username already exists."), }, ) ...略... from django.db.models.signals import post_save from django.dispatch import receiver class Profile(models.Model): user = models.OneToOneField(User, on_delete=models.CASCADE) CATEGORY_CHOICES = ( ('M', '男性'), ('F', '女性'), ('O', 'その他'), ) gender = models.CharField(max_length=20, blank=True, choices=CATEGORY_CHOICES) birth_date = models.DateField(null=True, blank=True) location = models.CharField(max_length=30, blank=True) favorite_words = models.CharField(max_length=50, blank=True) def __str__(self): return self.user.username def get_absolute_url(self): return reverse('account:profile', kwargs={'username': self.user.username}) @receiver(post_save, sender=User) def create_user_profile(sender, instance, created, **kwargs): if created: Profile.objects.create(user=instance) @receiver(post_save, sender=User) def save_user_profile(sender, instance, **kwargs): instance.profile.save()

views.py

from django.shortcuts import render, redirect from django.contrib.auth.forms import UserCreationForm from .forms import SignUpForm from django.views.generic import ( DetailView, ) from .models import Profile, User from .helpers import get_current_user from django.contrib.auth.mixins import LoginRequiredMixin, UserPassesTestMixin def signup(request): ... class ProfileDetailView(LoginRequiredMixin, DetailView): model = Profile template_name = 'account/profile.html' slug_field = 'user' slug_url_kwarg = 'user' #error change def get_context_data(self, **kwargs): context = super(ProfileDetailView, self).get_context_data(**kwargs) username = self.kwargs['username'] context['username'] = username context['user'] = get_current_user(self.request) return context

helper.py

from __future__ import absolute_import from django.contrib.sessions.models import Session from .models import User def get_current_user(request=None): if not request: return None session_key = request.session.session_key session = Session.objects.get(session_key=session_key).get_decoded() uid = session.get('_auth_user_id') return User.objects.get(id=uid)

urls.py

from django.urls import path from . import views from django.contrib.auth import views as auth_views app_name = 'account' urlpatterns = [ path('signup/', views.signup, name='signup'), path('login/', auth_views.LoginView.as_view(template_name='account/login.html'), name='login'), path('logout/', auth_views.LogoutView.as_view(template_name='account/logout.html'), name='logout'), path('profile/<slug:username>/', views.ProfileDetailView.as_view(), name='profile'), ]

profile.htmlへのリンク先

<a class="nav-item nav-link" href="{{ user.get_absolute_url }}">{{ user.username }}</a>

試したこと

adminページからプロフィール情報の入力を行いました。
urls.pyでprofile/slug:username/をprofile/slug:user/に変更すると以下エラーに変化しました。

NoReverseMatch at /admin/r/5/9/ Reverse for 'profile' with keyword arguments '{'username': 'name'}' not found. 1 pattern(s) tried: ['profile/(?P<user>[-a-zA-Z0-9_]+)/$'] Request Method: GET Request URL: http://127.0.0.1:8000/admin/r/5/9/ Django Version: 3.0.3 Exception Type: NoReverseMatch Exception Value: Reverse for 'profile' with keyword arguments '{'username': 'name'}' not found. 1 pattern(s) tried: ['profile/(?P<user>[-a-zA-Z0-9_]+)/$']

また、コードを作成する上で以下のサイトを参考にしました。
https://jyouj.hatenablog.com/entry/2018/05/30/221927
OSはWindows10です。よろしくお願いします。

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

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

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

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

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

guest

回答1

0

ベストアンサー

DetailViewは、URLpkまたはslugを必要とします。
URLにユーザー名を含めたいのであれば、TemplateViewでビューを実装するしかありません。

投稿2020/12/10 04:07

hasami

総合スコア1277

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

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

cetus

2020/12/10 14:57

ProfileDetailViewでslug_url_kwargを指定してget_absolute_urlでユーザー名を受け取りpath('profile/<slug:username>/', views.ProfileDetailView.as_view(), name='profile')でurlがつながると思ったんですがこれだとDetailViewを使うことはできないんですか? 参考にしたサイトではDetailViewを使用されていて同じ状況だと思ったんですが...
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問