Django - 返回没有字段的每个模型值

use*_*ser 6 python django

Priority模型具有三个值,对于每个值,我返回一个值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())
Run Code Online (Sandbox Code Playgroud)

模型.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"
Run Code Online (Sandbox Code Playgroud)

模板

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())
Run Code Online (Sandbox Code Playgroud)

ely*_*yas 2

您可以通过将数据与表单集一起使用来完成此操作(请参阅此处的initialDjango 文档)。

在您的views.py代码中,您可以添加此行来生成字段initial的一些值priority

initial = [{'priority': priority} for priority in Priority.objects.all()]
Run Code Online (Sandbox Code Playgroud)

然后将其传递给您的表单集:

data['priorities'] = PriorityChildFormset(initial=initial)
Run Code Online (Sandbox Code Playgroud)

请注意,initial需要一个与您创建的表单集长度相同的列表,该表单集由extra参数定义。这是有效的,因为这两个参数都是使用相同的基本查询集(即Priority.objects)定义的。如果应用了过滤器 - 则需要在两个地方都应用。

更改其显示方式

此外,如果您想防止priority用户使用下拉菜单更改字段,您可以传递widgets关键字参数以在生成的元素上inlineformset_factory设置属性,例如:disabled<select>

from django import forms
...

widgets={'priority': forms.Select(attrs={'disabled': True})}
Run Code Online (Sandbox Code Playgroud)

如果您希望该字段仅显示文本 - 这会更困难。我们想要的相关对象的字符串表示形式隐藏在用于生成每个<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 %}
Run Code Online (Sandbox Code Playgroud)