简体   繁体   English

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

[英]Django - return each model value without field

The Priority model has three values, for each of them values I'm returning an inlineform which allows the user to set a score for each priority & then save with the Project. Priority model 具有三个值,对于每个值,我将返回一个inlineform ,允许用户为每个优先级设置分数,然后与项目一起保存。

This is what it currently looks like: Current view这是它目前的样子:当前视图

My problem is: how can I automatically show all the priority values and allow the user to enter the score but not have to pick the Priority .我的问题是:如何自动显示所有优先级值并允许用户输入分数但不必选择Priority Is it possible to show it like the image below?是否可以像下图一样显示它?

What I'm trying to do.我正在尝试做的事情。

Views.py视图.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())

Models.py模型.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"

Template模板

<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>

You can do this by using initial data with your formset (see the Django documentation here ).您可以通过在表单集中使用initial数据来完成此操作(请参阅此处的 Django 文档)。

In your views.py code you can add this line to generate some initial values for the priority fields:在您的 views.py 代码中,您可以添加此行来为priority字段生成一些initial值:

initial = [{'priority': priority} for priority in Priority.objects.all()]

And then pass it to your formset:然后将其传递给您的表单集:

data['priorities'] = PriorityChildFormset(initial=initial)

Note that initial expects a list of the same length as the formset you created, which is defined by the extra parameter.请注意, initial需要一个与您创建的表单集长度相同的列表,该列表由extra参数定义。 This works because both of these parameters have been defined using the same base queryset (ie Priority.objects ).这是可行的,因为这两个参数都是使用相同的基本查询集(即Priority.objects )定义的。 If a filter were applied - it would need to apply in both places.如果应用了过滤器 - 它需要在两个地方都应用。

Changing how it displays改变它的显示方式

In addition, if you want to prevent the priority fields from being changed by the user using the dropdown menu, you can pass a widgets keyword argument to inlineformset_factory to set a disabled attribute on the <select> element that gets generated eg:此外,如果您想防止用户使用下拉菜单更改priority字段,您可以将widgets关键字参数传递给inlineformset_factory以在生成的<select>元素上设置disabled属性,例如:

from django import forms
...

widgets={'priority': forms.Select(attrs={'disabled': True})}

If you want the field to show only text - this is more difficult.如果您希望该字段显示文本 - 这更加困难。 The string representation of the related object that we want is buried in the field choices that are used to generate each <option> .我们想要的相关 object 的字符串表示隐藏在用于生成每个<option>的字段选择中。 If you want to do this, you can dig out each field manually:如果你想这样做,你可以手动挖出每个字段:

{% 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM