【问题标题】:Django inline formset with manytomany fields具有多字段的 Django 内联表单集
【发布时间】:2019-08-18 10:57:00
【问题描述】:

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

很多活动可以有很多人

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

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 模型中的所有人员和部分人员字段。

【问题讨论】:

    标签: django django-models django-forms


    【解决方案1】:

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

    【讨论】:

      猜你喜欢
      • 2018-03-08
      • 2018-03-02
      • 2015-12-05
      • 2010-10-08
      • 2015-02-28
      • 2011-06-10
      • 2015-03-08
      • 2019-05-15
      • 2019-04-23
      相关资源
      最近更新 更多