実現したいこと
こんにちは。
以下のことを実現したいのですが、form_invalidが発生していまい困っています。
お忙しところ恐れ入りますが質問させてください。
Djangoで以下のような画面を用意しました。
この画面からCustomUserモデルのフィールを編集できるようにしたいです。
![]
会員ランクはForeignKeyを使っています。参照先はRankモデルになります。
selectタグから項目を選ぶことができます。
この会員ランクを変更不可にして、名前とメールアドレスだけ更新できるようにしたいです。
発生している問題・エラーメッセージ
会員ランクのselectタグを変更できないようにdisabledに設定すると、 バリデーションが通らなくなりView(update_view.py)のform_invalidが発生するようになってしまいました。 なにか、解決策や代替案を頂けないでしょうか。
該当のソースコード
【update_view.pyのソース】 class UpdateView(OnlyYouMixin, UpdateView): model = CustomUser template_name = "act/update.html" form_class = UpdateForm success_url = reverse_lazy("watagashi_research:home") def form_valid(self, form): ctx = {'form': form} if self.request.POST.get('next') == 'confirm': # 更新内容の確認 return render(self.request, 'act/update_cnf.html', ctx) elif self.request.POST.get('next') == 'back': # 戻る return render(self.request, 'act/update.html', ctx) elif self.request.POST.get('next') == 'update': # 登録 return super().form_valid(form) 【CustomUserモデルのソース】 class CustomUser(AbstractBaseUser, PermissionsMixin): """ ユーザモデル """ # ユーザ名 username = models.CharField(verbose_name="名前", max_length=50, blank=False) # メールアドレス(ユーザを識別するためのキー) email = models.EmailField( verbose_name="メールアドレス", max_length=255, unique=True, blank=False, null=False) # メルマガ mail_magazine = models.BooleanField(verbose_name="メルマガ", default=True) # 登録日 created_at = models.DateField(verbose_name="登録日", auto_now_add=True) # 更新日 updated_at = models.DateField(verbose_name="更新日", auto_now=True) # 解約日 cancel_at = models.DateField( verbose_name="解約日", default=None, blank=True, null=True) # 会員ランク rank = models.ForeignKey( Rank, on_delete=models.CASCADE, verbose_name='会員ランク', default=1) # 有効フラグ Trueの場合、このアカウントでログイン可能(退会した場合これをFalseにする) is_active = models.BooleanField(verbose_name="アクティブ", default=True) # 管理者フラグ Trueの場合、管理画面にアクセスできる is_staff = models.BooleanField(verbose_name="スタッフ権限", default=False) # このFieldのレコードを一意に識別する USERNAME_FIELD = "email" # スーパーユーザ作成時に使用 REQUIRED_FIELDS = ["username"] objects = UserManager() def __str__(self): return self.username def get_absolute_url(self): return reverse_lazy('accounts:signup') 【Rankモデルのソース】 class Rank(models.Model): """ 会員ランクモデル Rank 1: 無料会員, 2: 有料会員(サブスク), 3: 有料会員(買い切り) 4: 有料会員+オプション有 """ # ランク rank = models.CharField(verbose_name="ランク", max_length=1, default=1) # ランク名 name = models.CharField(verbose_name="ランク名", max_length=50, blank=False) # 登録日 created_at = models.DateField(verbose_name="登録日", auto_now_add=True) # 更新日 updated_at = models.DateField(verbose_name="更新日", auto_now=True) def __str__(self): return self.name 【UpdateFormフォームのソース】 class UpdateForm(forms.ModelForm): class Meta: model = CustomUser fields = ['username', 'email', 'rank'] def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.fields['username'].widget.attrs['class'] = 'form-control signup-name' self.fields['email'].widget.attrs['class'] = 'form-control signup-email' self.fields['rank'].widget.attrs['class'] = 'form-control signup-email' self.fields['rank'].widget.attrs['disabled'] = 'disabled' 【update.htmlのソース】 <div class="row g-0 app-auth-wrapper"> <div class="d-flex flex-column align-content-end"> <div class="app-auth-body mx-auto"> <h2 class="auth-heading text-center mb-4">ユーザープロフィール更新</h2> <div class="text-center">以下に必要事項を入力してください。</div> <div class="auth-form-container text-start mx-auto"> <form method="POST" class="auth-form auth-signup-form"> {% csrf_token %} <div class="email mb-3"> <label class="sr-only" for="signup-email">{{ form.username.label }}</label> {{ form.username }} </div> <div class="email mb-3"> <label class="sr-only" for="signup-email">{{ form.email.label }}</label> {{ form.email }} </div> <div class="email mb-3"> <label class="sr-only" for="signup-email">{{ form.rank.label }}</label> {{ form.rank }} </div> <div class="text-center"> <button type="submit" class="btn app-btn-primary w-100 theme-btn mx-auto" name="next" value="confirm">更新内容を確認する</button> </div> </form><!--//auth-form--> </div><!--//auth-form-container--> </div><!--//auth-body--> <footer class="app-auth-footer"> <div class="container text-center py-3"> <!--/* This template is free as long as you keep the footer attribution link. If you'd like to use the template without the attribution link, you can buy the commercial license via our website: themes.3rdwavemedia.com Thank you for your support. :) */--> <small class="copyright">Designed with <i class="fas fa-heart" style="color: #fb866a;"></i> by <a class="app-link" href="http://themes.3rdwavemedia.com" target="_blank">Xiaoying Riley</a> for developers</small> </div> </footer><!--//app-auth-footer--> </div><!--//flex-column--> </div><!--//row-->
調べたこと・わかったこと
会員ランクはselectタグで、Djangoはselectタグをdisabledにしたらpostされない仕組みのようです。
なので、form_invalidが発生していると思います。
補足情報(FW/ツールのバージョンなど)
asgiref==3.4.1
autopep8==1.5.7
Django==3.2.8
django-localflavor==3.1
flake8==4.0.1
gunicorn==20.1.0
mccabe==0.6.1
mysqlclient==2.0.3
pycodestyle==2.8.0
pyflakes==2.4.0
PyMySQL==1.0.2
python-stdnum==1.17
pytz==2021.3
sqlparse==0.4.2
toml==0.10.2
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。