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

时间:2019-08-18 10:57:00

标签: django django-models django-forms

我花了很多时间在这个问题上进行搜索,却没有找到一些最新的答案。我正在尝试创建一个创建数据库条目的表单。基本思路是这样的:

  

许多活动可以有很多人

因此,这里的难题是用户需要创建一个事件,用户可以选择所有参加会议的人。但是,每个参加的人都有某些事情,每个事件也需要跟踪。参见下面的模型:

models.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视图,并遇到了这种情况:

  

ValueError:“ roster.Person”没有指向“ roster.Raid”的外键。

forms.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模型中的某些人员字段。

1 个答案:

答案 0 :(得分:0)

您可以做的另一件事是使用DjangoRestFramework。 使用rest,您可以先将人员数据发送到前端,然后在前端中可以创建Event并为每个事件添加人员详细信息,最后使用javascript发布所有这些数据。尝试一下,它肯定会起作用。