具有许多字段的 Django 内联表单集

标签 django django-models django-forms

我花了相当多的时间搜索这个主题,但没有找到一些真正最新的答案。我正在尝试创建一个创建数据库条目的表单。基本思想是这样的:

Many events can have many people

因此,这里的困难在于用户需要创建一个事件,用户可以在其中选择所有参加的人。但是,每个参加的人都有某些事情也需要在每个事件中进行跟踪。请参阅以下模型:

模型.py

from django.db import models
from django.contrib.auth.models import User[]


class PersonRole(models.Model):
    role = models.CharField(max_length=20, choices=ROLE_CHOICES, unique=True)

    # this function will be invoked when this model object is foreign key of other model(for example Employee model.).
    def __str__(self):
        return self.role


class PersonClass(models.Model):
    name = models.CharField(max_length=100, choices=CLASS_CHOICES, unique=True)
    color = models.CharField(max_length=6, choices=COLOR_CHOICES, unique=True)

    # this function will be invoked when this model object is foreign key of other model(for example Employee model.).
    def __str__(self):
        return self.name


class Person(models.Model):
    name = models.CharField(max_length=100, unique=True)
    personclass = models.ForeignKey(PersonClass, on_delete=models.CASCADE, blank=True, null=True)
    personrole = models.ForeignKey(PersonRole, on_delete=models.CASCADE, blank=True, null=True)
    value = models.IntegerField(default=0)
    reliability = models.IntegerField(default=0)
    last_item = models.DateField(auto_now=False, blank=True, null=True)
    last_event_attended = models.DateField(auto_now=False, blank=True, null=True)
    last_manager_attended = models.DateField(auto_now=False, blank=True, null=True)
    item_received = models.BooleanField(default=False)
    note = models.TextField(null=True, blank=True)
    core_attendee = models.BooleanField(default=False)
    enabled = models.BooleanField(default=True)

    # this function will be invoked when this model object is foreign key of other model(for example Employee model.).
    def __str__(self):
        return self.name


class Location(models.Model):
    name = models.CharField(max_length=100, unique=True)

    # this function will be invoked when this model object is foreign key of other model(for example Employee model.).
    def __str__(self):
        return self.name


class Boss(models.Model):
    name = models.CharField(max_length=100, unique=True)
    location = models.ForeignKey(Location, on_delete=models.CASCADE)

    # this function will be invoked when this model object is foreign key of other model(for example Employee model.).
    def __str__(self):
        return self.name


class Raid(models.Model):
    date = models.DateTimeField(auto_now_add=True)
    boss = models.ForeignKey(Boss, on_delete=models.CASCADE, null=True, blank=True)
    success = models.BooleanField()
    attendees = models.ManyToManyField(Person)
    created_by = models.ForeignKey(User,
        related_name="raids", blank=True, null=True,
        on_delete=models.SET_NULL)

    # this function will be invoked when this model object is foreign key of other model(for example Employee model.).
    def __str__(self):
        return str(self.date)

我已经开始尝试使用通用的内置 create\update\delete View 并遇到了这个问题:

ValueError: 'roster.Person' has no ForeignKey to 'roster.Raid'.

表单.py

class RaidGenericCreateModelForm(forms.ModelForm):
    class Meta:
        model = Person
        exclude = ()


RaidPersonFormSet = inlineformset_factory(Raid, Person, fields=['name', 'personclass', 'personrole', 'item_received'], extra=1, can_delete=False)

views.py

class RaidCreate(CreateView):
    model = Raid
    template_name = 'roster/raid_create.html'
    form_class = RaidGenericCreateModelForm
    success_url = None

    def get(self, request, *args, **kwargs):
        self.object = None
        form_class = self.get_form_class()
        form = self.get_form(form_class)
        person_form = RaidPersonFormSet
        return self.render_to_response(
            self.get_context_data(form=form,
                                  person_form=person_form
                                  )
        )

有 9 年前的帖子说您不能对多对多字段使用 inlineformset_factory。所以我的问题是,我有哪些选择?简单地创建事件(在模型中称为 Raid)并同时从名册中选择人员(称为 Person)的最佳方法是什么> 在模型中)并更改这些人为该事件与他们关联的选项

作为我在这里尝试完成的示例: 事件 1

-人A(选中,item_received=True)

-B人(选中,item_received=False)

-C 人(选中,item_received=False)

-D人(未选中,item_received=False)

事件 2

-人A(选中,item_received=False)

-B人(未选中,item_received=False)

-C 人(选中,item_received=True)

-D人(选中,item_received=False)

人员列表显示所有人员和 Person 模型中的部分人员字段。

最佳答案

您可以做的替代方法是使用 DjangoRestFramework以此目的。 使用 rest,您可以首先将人员数据发送到前端,然后在前端您可以创建事件并为每个事件添加人员详细信息,最后使用 javascript 发布所有数据。试试吧,它肯定会起作用。

关于具有许多字段的 Django 内联表单集,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57543872/

相关文章:

python - 反转 'password_change_done',参数 '()' 和关键字参数 '{}' 未找到

python - 在 models.py : Django rest framwork 中导入序列化器

Django : ModelForm with conditions

python - 模块'对象没有属性 'SelectDateWidget'

django - ssl 与 django Gunicorn 和 nginx

django - 如何在 django-registration 应用程序中禁用电子邮件激活?

sql - Django 聚合计数

python - ModelForm 返回服务器错误 (500)

django - 如何通过一些计算从不同的 ModelForm 字段中填充模型字段值?

python - 子类 HttpResponse 以在 Django 中获取 JSON 输出