Reputation: 2475
Ive spent a fair bit of time searching on this subject without finding some real up to date answers. I'm trying to create a form that creates a db entry. The basic idea is this:
Many events can have many people
So, the struggle here is that the user needs to create an event where the user can select all the people that attend. Each person that attends though, has certain things that also needs to be tracked per event. See the model below:
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)
I've started down the path of just trying to use the generic in-built create\update\delete views and ran into this:
ValueError: 'roster.Person' has no ForeignKey to '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
)
)
There are 9-year old posts that say you cannot use inlineformset_factory with many to many fields. So my question here is, what are my options? What is the best way to go about simply creating an Event (referred to as Raid
in the model) and at the same time selecting the people from the roster (referred to as Person
in the model) and changing the options those people have associated to them for that event?
As an example of what I am trying to accomplish here: Event 1
-Person A (selected, item_received=True)
-Person B (selected, item_received=False)
-Person C (selected, item_received=False)
-Person D (not selected, item_received=False)
Event 2
-Person A (selected, item_received=False)
-Person B (not selected, item_received=False)
-Person C (selected, item_received=True)
-Person D (selected, item_received=False)
Where the list of persons is showing all persons and some of the persons fields from the Person
model.
Upvotes: 3
Views: 299
Reputation: 897
The alternate thing you can do is use DjangoRestFramework for this purpose. Using rest you can first send persons data to frontend then in frontend you can create Event and add person details for each event,and in last post all that data using javascript.Try it,it will surely work.
Upvotes: 1