我试图将所有类别显示为一个列表,我可以单击并从中进行选择,这只是我管理面板中内容的精确复制品,但它仍然显示为不可单击的列表。
forms.py
class ProfileEditForm(forms.ModelForm):
"""
Form for updating Profile data
"""
class Meta:
model = Profile
fields = [
"first_name",
"last_name",
"about_me",
"profile_image",
"username",
"email",
"categories",
]
first_name = forms.CharField(label="First Name", max_length=63, required=False)
last_name = forms.CharField(label="Last Name", max_length=63, required=False)
about_me = forms.CharField(label="About Me", max_length=511, required=False)
email = forms.EmailField(label="Email", disabled=True)
username = forms.CharField(label="Username", disabled=True)
profile_image = forms.ImageField(required=False)
categories = forms.ModelMultipleChoiceField(
queryset=Category.objects.all(),
required=False,
widget=forms.CheckboxSelectMultiple(),
)
profile.models.py
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE, related_name="profile")
first_name = models.CharField(max_length=63, blank=False)
last_name = models.CharField(max_length=63, blank=False)
about_me = models.CharField(max_length=511, blank=True)
categories = models.ManyToManyField(
Category, related_name="user_categories", symmetrical=False
)
categories.models.py
from django.db import models
class Category(models.Model):
name = models.CharField(max_length=63)
created = models.DateTimeField(auto_now_add=True, blank=True, null=True)
last_modified = models.DateTimeField(auto_now=True, blank=True, null=True)
def __str__(self):
return self.name
def __unicode__(self):
return self.name
class Meta:
verbose_name_plural = "Categories"
settings.html
<div class='row'>
<div class="col s12 m6">
{{form.categories.errors}}
{{form.categories.label_tag}}
{{form.categories}}
</div>
</div>
最佳答案
您需要创建表单本身:
<form method='post'>
</form>
并在新行上打印每个字段:
{{ form.as_p }}
是安全检查。
{% csrf_token %}
在 View 中,我留下了get_context_data。在其中,您可以向上下文添加值,例如,如下所示:
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['rubrics'] = Car.objects.all()
将 bboard 替换为放置模板的文件夹的名称。 我有这个:templates/bboard,位于应用程序文件夹中。
在表单 View 中,CreateView使用class,其中:template_name - 显示页面的模板名称,form_class - 表示表单类,success_url - 保存表单成功时返回的位置(本例中是同一个页面)与表单),get_context_data - 模板上下文(您可以将其打印出来并查看里面的内容)。
如果你的模型有字段:first_name、last_name、about_me、email、username、profile_image,那么你在 Meta 类中指定 fields 变量就足够了。您不需要在表单中重新创建它们。
template_name = 'bboard/tam_form.html'#bboard replace with your prefix
模板
<form method='post'>
{{form.categories.errors}}
{% csrf_token %}
{{ form.as_p }}
<input type="submit" value='adding'>
</form>
View .py
from .forms import *
from django.views.generic.edit import CreateView
from django.urls import reverse_lazy
class Profile(CreateView):
template_name = 'bboard/settings.html'#bboard replace with your prefix
form_class = ProfileEditForm
success_url = reverse_lazy('test')
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
return context
url.py
from django.urls import path
from .views import *
urlpatterns = [
path('test/', Profile.as_view(), name='test'),
]
2022 年 11 月 13 日更新 这是当我转到以下地址时我的表单的样子:
http://localhost:8000/test/
但是表单没有提交。我对此没有太多经验。我可以假设 forms.ModelForm 期望模型具有这样的字段,因为如果您删除包含电子邮件、用户名、profile_image 的行,并将它们从字段中删除并将“用户”添加到字段中,那么数据将保存在数据库(选中)。
正如我之前所说,如果在字段中声明了字段,那么您不需要再次定义它们(如果保留它们,表单也会被保存)。表单类如下所示:
class ProfileEditForm(forms.ModelForm):
class Meta:
model = Profile
fields = [
'user',
'first_name',
'last_name',
'about_me',
'categories',
]
categories = forms.ModelMultipleChoiceField(
queryset=Category.objects.all(),
required=False,
widget=forms.CheckboxSelectMultiple(),
)
关于python - Django 模型多选表单无法正确呈现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/74365546/