【问题标题】:Django / Bootstrap Error: Parameter "form" should contain a valid Django FormDjango / Bootstrap 错误:参数“form”应包含有效的 Django 表单
【发布时间】:2020-02-09 04:17:12
【问题描述】:

我有一个名为“Accounts”的 Django 应用程序,它扩展了 Django 默认用户模型。我希望每个用户都能够更新他们的帐户,这是一个使用 generic.UpdateView 的名为 UserProfile 的模型。转到 UpdateView URL 时出现以下错误:

/accounts/user-profile/5/edit/ 处的 BootstrapError 参数“form”应该包含一个有效的 Django 表单。

我在下面包含了我的代码。谢谢!

models.py

from django.db import models
from django.contrib import auth

# Create your models here.

class User(auth.models.User,auth.models.PermissionsMixin):
    readonly_fields = ('id','pk')

    def __str__(self):
        return self.username

class UserProfile(models.Model):
    user = models.OneToOneField(auth.models.User,on_delete=models.CASCADE)
    join_date = models.DateTimeField(auto_now=True)
    profile_pic = models.ImageField(upload_to='profile_pics',default='media/block-m.png')
    skills = models.TextField()
    major = models.CharField(max_length=128)
    grad_year = models.CharField(max_length=4)
    clubs = models.TextField() #make FK to Clubs
    opt_in = models.BooleanField(default=True)

    def __str__(self):
        return self.user.username

forms.py

from django.contrib.auth import get_user_model
from django.contrib.auth.forms import UserCreationForm
from django.contrib.auth.models import User
from .models import UserProfile
from django import forms

class UserCreateForm(UserCreationForm):

    class Meta:
        model = get_user_model()
        fields = ('first_name','last_name','username','email','password1','password2')

    def __init__(self,*args,**kwargs):
        super().__init__(*args,**kwargs)
        # self.fields['username'].label = 'Username'
        # self.fields['email'].label = 'Email Address'
        # self.fields['password1'].label = 'Password'
        # self.fields['password2'].label = 'Confirm Password'

class UserProfileForm(forms.ModelForm):
    class Meta:
        model = UserProfile
        fields = ('profile_pic','grad_year','opt_in')

views.py

from django.shortcuts import render,redirect
from django.contrib import messages
from django.contrib.auth.mixins import(
    LoginRequiredMixin,
    PermissionRequiredMixin
)
from django.urls import reverse,reverse_lazy
from django.db import IntegrityError
from django.shortcuts import get_object_or_404
from django.views import generic
from .models import User,UserProfile
from .forms import UserCreateForm,UserProfileForm
import easygui
from . import models

from . import forms

# Create your views here.


class ListAccounts(generic.ListView):
    model = models.UserProfile

class DetailAccounts(generic.DetailView):
    model = models.UserProfile

class UpdateAccounts(generic.UpdateView):
    fields = ('grad_year',)
    model = models.UserProfile

def SignUp(request):

    registered=False

    if request.method == "POST":
        user_create_form = UserCreateForm(data=request.POST)
        user_profile_form = UserProfileForm(data=request.POST)

        if user_create_form.is_valid() and user_profile_form.is_valid():
            user = user_create_form.save()

            user_profile = user_profile_form.save(commit=False)
            user_profile.user = user


            if 'profile_pic' in request.FILES:
                user_profile.profile_pic = request.FILES['profile_pic']

            user_profile.save()

            registered = True

            return redirect('/accounts/login/')

        else:
            print(user_create_form.errors,user_profile_form.errors)
    else:
        user_create_form = UserCreateForm()
        user_profile_form = UserProfileForm()

    return render(request,'accounts/signup.html',
        {'user_create_form':user_create_form,
         'user_profile_form':user_profile_form,
         'registered':registered})

urls.py

from django.contrib.auth import views as auth_views
from . import views

app_name = 'accounts'

urlpatterns = [
    path('login/',auth_views.LoginView.as_view(template_name='accounts/login.html'),name='login'),
    path('logout',auth_views.LogoutView.as_view(),name='logout'),
    path('',views.ListAccounts.as_view(),name='all'),
    path('signup/',views.SignUp,name='signup'),
    path('user-profile/<int:pk>/',views.DetailAccounts.as_view(),name='detail'),
    path('user-profile/<int:pk>/edit/',views.UpdateAccounts.as_view(),name='user_update'),
    path('match/',views.Match.as_view(),name='match'),
]

userprofile_form.html

{% extends 'base.html' %}
{% load bootstrap4 %}

{% block content %}

<div class="container login">
    <h2>Update</h2>
    <form action="{% url 'accounts:all' %}" enctype="multipart/form-data" method="POST">
      {% csrf_token %}
      {% bootstrap_form user_profile_form layout='inline' %}
      <input type="submit" class="btn" style="background:#f86041; color:white;" value="Update">
    </form>
</div>

{% endblock %}

【问题讨论】:

  • 也许这个类似的问题会有所帮助:stackoverflow.com/questions/34847762/…
  • 我尝试了那个,然后得到一个 404 错误,上面写着“没有用户与给定的查询匹配”。但是,我可以查看该用户的个人资料页面。例如,DetailView 将位于 /accounts/user-profile/6/ 但 URL /accounts/user-profile/6/edit/ 显示“没有用户与给定的查询匹配”,即使我知道 pk= 的用户6 存在,我可以查看他们的 DetailView 个人资料页面。
  • 你能提供完整的追溯吗?此外,您的服务器是否给出了 500 错误,并在您的 cli 中抛出了消息,或者您是否在呈现的 html 中收到错误消息?

标签: python django bootstrap-4


【解决方案1】:

我将尝试解释我为尝试解决此问题所采取的步骤,以便您更好地了解如何自己解决:

首先,您需要了解引发错误的原因。这是BootstrapError 不是标准错误,因此您需要查看django-bootstrap4 的源代码以了解它为什么会出现。查看源代码(只需搜索)你会发现:

        if not isinstance(form, BaseForm):
            raise BootstrapError('Parameter "form" should contain a valid Django Form.')

尝试从调用模板标记的位置到引发此错误的位置(查看回溯也可能对您有所帮助)了解所有各种变量的含义。

在您的情况下,form 将等于user_profile_form,并且由于user_profile_form 不是BaseForm 的实例(从django.forms.forms 导入)而引发错误。所以你可以回去看看user_profile_form。它是UserProfileForm 的一个实例,它又是ModelForm 的子类。但是ModelFormBaseForm 的子类。嗯……这似乎有点奇怪。为什么user_profile_form 不是BaseForm 的实例,而应该是。

此时,首先检查拼写错误等内容?也许检查您的中间件是否可以完全使用表单。另外,尝试简化一些事情,只需渲染表单 {{ user_profile_form }}... 你会发现这不起作用。所以问题似乎出在user_profile_form

啊哈...我们已将user_profile_form 传递给视图中的模板SignUp但这不是我们在这里看到的视图!!!我们正在考虑的视图是UpdateAccounts 视图。这是一个generic.UpdateView,如果我们查看 django 文档(总是一个好主意)并查看示例,我们会看到表单被传递给模板,就像 form

换行:

      {% bootstrap_form user_profile_form layout='inline' %}

      {% bootstrap_form form layout='inline' %}

在模板userprofile_form.html 中,它应该都能正常工作:)

如您所见,在我偶然发现(也许更明显)正确的解决方案之前,我走了一些死胡同。但我希望这会有所帮助。

【讨论】:

    猜你喜欢
    • 2019-11-18
    • 2016-04-23
    • 1970-01-01
    • 2019-02-09
    • 1970-01-01
    • 1970-01-01
    • 2017-06-14
    • 1970-01-01
    • 2012-04-12
    相关资源
    最近更新 更多