1

I'm pretty new to Django and I am working on a project that currently requires the following:

I have two basic structures: a Project model and a TeamMember model- both related to each other through a ManytoMany relationship. Then I have an TMAssigned 'through' class. The team member will have many projects assigned to it over time.

I have a ModelFrom which creates a Project model through the creation of the form.

My question is, How do I link the team member to the newly created project upon the submission of the form?

Here is a bit of my model & form code:

TeamMember

class TeamMember(models.Model):
    firstname = models.CharField(max_length=100, default= "First Name")
    lastname = models.CharField(max_length=100, default= "Last Name")
    fullname = models.CharField(max_length=100, default= "Full Name")
    email = models.EmailField(max_length=254)
    cellphone = PhoneNumberField(null=False, blank=False, unique=True)
    numberofcases = models.IntegerField(max_length=10000, default=0)

    @property
    def fullnamefunc(self):
        fullname = "{} {}".format(self.firstname, self.lastname)
        return fullname

    def __str__(self):
        return self.fullname

Project

class Project(models.Model):
    pursuitname = models.CharField(max_length=500)
    datecreated = models.DateTimeField(auto_now=True)
    bdmember = models.ManyToManyField('team.TeamMember')

Views.py

class bdFormView(TemplateView):
    template_name = os.path.join(BASE_DIR, "templates/masterform/bdform.html")

    def get(self,request):
        form = bdForm()
        return render (request, self.template_name, {'form': form})

    def post(self, request):
        form = bdForm(request.POST)

        if form.is_valid():
            print("form is valid")

            project = form.save(commit=False)
            project.save()
            text = form.cleaned_data['briefcard']

Form.py

class bdForm(forms.ModelForm):

            bdmemberlist = TeamMember.objects.all().order_by('lastname')
            pursuitname = forms.CharField()
            bdmember = forms.ModelChoiceField(queryset= bdmemberlist)
            addbdteam = forms.ModelMultipleChoiceField(
            queryset=TeamMember.objects.all().order_by('lastname'), widget=Select2MultipleWidget,  required=False)



            class Meta:
                model = Project
                fields = ['pursuitname','addbdteam','bdmember',]



        def __init__(self, *args, **kwargs):

            if kwargs.get('instance'):
                initial = kwargs.setdefault('initial', {})
                initial['projects'] = [t.pk for t in
                    kwargs['instance'].project_set.all()]

            forms.ModelForm.__init__(self, *args, **kwargs)

        def save(self, commit=True):
            instance = forms.ModelForm.save(self, False)
            old_save_m2m = self.save_m2m

            def save_m2m():
                old_save_m2m()

                for project in self.cleaned_data['bdmember']:
                    instance.teammember_set.add(project)

Thanks in advance!!

Edit- after doing some more research, I've removed the "Through" model from the script and am trying to rely on the form.py save method to do the join. However, when I do this- the two are still not linking up properly.

mg2019
  • 191
  • 17
  • Why are you using a ManyToMany relationship? Can multiple team members be assigned a single project? – Rene Oct 19 '19 at 09:57
  • Take a look at this great response that breaks down various relationships at the SQL level. https://stackoverflow.com/a/19644725 – Rene Oct 19 '19 at 10:02
  • @Rene that is correct, multiple Team members will be assigned to the same project. Thank you for the article- it did help with understanding relationships a bit more, but I'm still confused of how to trigger the manytomany relationship through a form submission. thank you! – mg2019 Oct 19 '19 at 14:18
  • @Rene - are you saying that you think the manytomany field is in the wrong Model? as in it should be within Project instead of TeamMember? If thats the case- what if I have a different model named Broker that is like a TeamMember, in that it can be assigned multiple projects, and even the same Projects as a TeamMember. So that a Project can have both multiple Brokers and Team Members? Thanks again... – mg2019 Oct 19 '19 at 14:25
  • I need some more clarification. Will a team member fill out and submit the Modelform then automatically have it assigned to him/her? Or do you want some administrator (just as an example) to assign users as he fills out the form? – Rene Oct 19 '19 at 14:38
  • @Rene It would be the latter. An Admin user will log in, and fill out the form and assign the "users" to the Project. The Brokers and TeamMembers wont behave as actual users within the database- as in they will not have a login account. – mg2019 Oct 19 '19 at 20:35
  • @Rene - I did a bit more research and removed the "Through" model, however- I'm starting to think that I should have created the form under the TeamMember app instead of the Project app- does that sound more accurate? I'd like to avoid this if possible though since I have more than one type of user (as mentioned, TeamMember and Broker) Thanks again! – mg2019 Oct 19 '19 at 21:58
  • Take a look at my answer below. That's the course of action I recommended (deleting the through form with some extra context). Creating it via the Project app would be simpler, but it's ultimately up to you :-) Unless you're on a deadline, trial and error always works. But you may have to flush the migrations once or twice – Rene Oct 19 '19 at 22:29
  • You are trying to do two things at once. One is to generate a Project. Do just that. Then, in another page, associate the project and teammember with an explicit m2m table (e.g. "project has member", with a time to start and stop). See e.g. this post for an explicit 'through' table. – roadrunner66 Oct 20 '19 at 03:00
  • @roadrunner66, That would be idea for a CRM/ticketing type system where the Projects are maintained as time progresses- however, the purpose of this project is purely to generate a record for dashboards and reporting. Is it even possible to do both things at once within Django? Thanks for the reply! – mg2019 Oct 20 '19 at 03:19
  • Then leave out the times. It's still m2m like you started. I forgot to append the example with the explicit through table: https://stackoverflow.com/questions/18117113/how-to-make-django-manytomany-relationships-explicit-on-the-receiving-models-en – roadrunner66 Oct 20 '19 at 03:42
  • @roadrunner66 I think I understand what you are saying, though please correct me if I'm wrong. I should re-add the "Through" models for Teammembers- then use something like Formsets to activate the union between the TeamMembers and the Projects? If this is so, how do I trigger both the creation of a project and the union within a Through model at the same time? – mg2019 Oct 20 '19 at 18:28

1 Answers1

0

Since only your admin (superusers?) will log in, you can start off by using the in-built Django Admin.

I would recommend this for you, at least for now, because you're a beginner and the Admin Form is stunningly simple to use. Then, you can create a custom form later on when you're more comfortable. :-)

With this in mind, you can try eliminating the 'through' table (you may need to reset your migrations), and try this.

Admin.py

from django.contrib import admin
from .models import TeamMember, TMAssigned, Project, 

TeamMembersInLine(admin.TabularInline):
    model = TeamMember
    extra = 1

@admin.register(Project):
class ProjectAdmin(admin.ModelAdmin):
    list_display = ('pursuitname', 'bdmember ', 'datecreated')
    inlines = [TeamMembersInLine]

Here's another answer that delves into the through table. It was asked by someone in your situation and the answer is relevant too.

Rene
  • 370
  • 3
  • 14
  • Thanks so much, @Rene- though I think I need to stick with the custom form strategy rather than using the Admin panel. Do you know of a way for me to link up these manytomany relationships through the form I have above? Thanks so much again! – mg2019 Oct 19 '19 at 23:15