[英]Django - return each model value without field
Priority
model 具有三个值,对于每个值,我将返回一个inlineform
,允许用户为每个优先级设置分数,然后与项目一起保存。
这是它目前的样子:当前视图
我的问题是:如何自动显示所有优先级值并允许用户输入分数但不必选择Priority
。 是否可以像下图一样显示它?
视图.py
class ProjectCreateview(LoginRequiredMixin, CreateView):
model = Project
form_class = ProjectCreationForm
login_url = "/login/"
success_url = '/'
def get_context_data(self, **kwargs):
PriorityChildFormset = inlineformset_factory(
Project, ProjectPriority, fields=('project', 'priority', 'score'), can_delete=False, extra=Priority.objects.count(),
)
data = super().get_context_data(**kwargs)
if self.request.POST:
data['priorities'] = PriorityChildFormset(self.request.POST)
else:
data['priorities'] = PriorityChildFormset()
return data
def form_valid(self, form):
context = self.get_context_data()
prioritycriteria = context["priorities"]
form.instance.creator = self.request.user
self.object = form.save()
prioritycriteria.instance = self.object
if prioritycriteria.is_valid():
prioritycriteria.save()
return HttpResponseRedirect(self.get_success_url())
模型.py
class Priority(models.Model):
title = models.CharField(verbose_name="Priority Name", max_length=250)
def __str__(self):
return self.title
class Project(models.Model):
name = models.CharField(verbose_name="Name", max_length=100)
details = models.TextField(verbose_name="Details/Description", blank=False)
creator = models.ForeignKey(User, on_delete=models.CASCADE)
class ProjectPriority(models.Model):
project = models.ForeignKey(Project, on_delete=models.CASCADE)
priority = models.ForeignKey(Priority, on_delete=models.CASCADE)
score = models.CharField(max_length=1000, choices=priority_choices)
class Meta:
verbose_name = "Priority"
verbose_name_plural = "Priorities"
模板
<table class="table table-light">
<tbody>
{{ priorities.management_form }}
{% for priority in priorities.forms %}
<tr>
{% for field in priority.visible_fields %}
<td>
{{ field.errors.as_ul }}
{{ field }}
</td>
{% endfor %}
</tr>
{% endfor %}
</tbody>
</table>
您可以通过在表单集中使用initial
数据来完成此操作(请参阅此处的 Django 文档)。
在您的 views.py 代码中,您可以添加此行来为priority
字段生成一些initial
值:
initial = [{'priority': priority} for priority in Priority.objects.all()]
然后将其传递给您的表单集:
data['priorities'] = PriorityChildFormset(initial=initial)
请注意, initial
需要一个与您创建的表单集长度相同的列表,该列表由extra
参数定义。 这是可行的,因为这两个参数都是使用相同的基本查询集(即Priority.objects
)定义的。 如果应用了过滤器 - 它需要在两个地方都应用。
此外,如果您想防止用户使用下拉菜单更改priority
字段,您可以将widgets
关键字参数传递给inlineformset_factory
以在生成的<select>
元素上设置disabled
属性,例如:
from django import forms
...
widgets={'priority': forms.Select(attrs={'disabled': True})}
如果您希望该字段仅显示文本 - 这更加困难。 我们想要的相关 object 的字符串表示隐藏在用于生成每个<option>
的字段选择中。 如果你想这样做,你可以手动挖出每个字段:
{% for priority in priorities.forms %}
<tr>
<td>
{{ priority.priority.errors.as_ul }}
{% for value, name in priority.priority.field.choices %}
{% if value == priority.priority.value %}
{{ name }}
{% endif %}
{% endfor %}
{{ priority.priority.as_hidden }}
</td>
<td>
{{ priority.score.errors.as_ul }}
{{ priority.score }}
</td>
</tr>
{% endfor %}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.