title: How can I create a related object in Django 2.0+, simply and effectively?
body: <p>I'd like to find a simple and robust way to create a child object. I think it is a simple problem, probably solved using Django RelationshipManager or Related objects reference. </p>
  
  <p>I've gotten it to work in the past (by paying someone on fiver to help me solve this), but I feel that there is a much simpler method that escapes me.</p>
  
  <p>This worked on my <strong>views.py</strong></p>
  
  <pre class="lang-py prettyprint-override"><code>class MainVisitForm(SingleObjectMixin, FormView):
      template_name = "clincher/visit_form.html"
      form_class = VisitForm
      model = Main
  
      def post(self, request, *args, **kwargs):
          if not request.user.is_authenticated:
              return HttpResponseForbidden()
          self.object = self.get_object()
  
  
  
          form=self.get_form()
          form.fk_visit_user = self.request.user
          form.fk_visit_main = Main.objects.get(id=self.kwargs['pk'])
          #added this to save form as we are mixxing the two forms and Models
          # as the approch of singleObjectMixin is we should get object from DB as per request url as a primary key
          #and we have defined  model as a Main but taking the form view of VistForm as the probem occures
          # as i think
  
  
          if form.is_valid():
              instance = Main()
              instance.firstname = form.cleaned_data['firstname']
              instance.middelname = form.cleaned_data['middlename']
              instance.lastname = form.cleaned_data['lastname']
              instance.date_of_birth = form.cleaned_data['date_of_birth']
              instance.sex = form.cleaned_data['sex']
  
              instance.address = form.cleaned_data['address']
              instance.save()
  
          return super().post(request, *args, **kwargs)
  
  
      def get_success_url(self):
          return reverse('clincher:main_detail', kwargs={'pk': self.object.pk})
  </code></pre>
  
  <p>Basically, while the user is in the details page of the "main" object, I would like them to be able to create a child object (visit object). Ultimately 1 patient will have many visits (1:m relationship). Each time a patient visits the doc, 1 new visit will be added, that is related to that person. Later, I will show a list of visits for that patient (but not the subject of this question).</p>
  
  <p><strong>Models.py</strong></p>
  
  <pre class="lang-py prettyprint-override"><code>class Main(models.Model):
      firstname = models.CharField(max_length = 256, verbose_name=('First Name'))
      middlename = models.CharField(max_length=256, verbose_name=('Middle Name'))
      lastname = models.CharField(max_length=256, verbose_name=('Last Name'))
      date_of_birth = models.DateField()
      age = models.CharField(max_length=4)
      sex_list = (
          (str(1), 'Female'),
          (str(2), 'Male'),
          (str(3), 'Other'),
          (str(4), 'Unknown'),)
      sex = models.CharField(max_length = 24, choices=sex_list, verbose_name='Sex')
      address = models.TextField(max_length = 256)
  
      @property
      def full_name(self):
          #"Returns the person's full name."
          return '%s %s' % (self.firstname, self.lastname)
  
      #Redirects after form is submitted using primary key
      def get_absolute_url(self):
          return reverse('clincher:main_detail', kwargs={'pk': self.pk})
  
      def __str__(self):
          return self.firstname + ' ' + self.lastname +' - ' + str(self.date_of_birth)
  
  
  
  
  class Visit(models.Model):
      fk_visit_main = models.ForeignKey(Main, on_delete=models.CASCADE, verbose_name=('Patient Name'))
      visit_date = models.DateField(auto_now = True, editable=True)
      fk_visit_user = models.ForeignKey(User, on_delete=models.PROTECT, verbose_name=('Practitioner'), max_length=500)
      visit_label = models.CharField(max_length=256, blank=True, null=True)
      visit_type = models.CharField(
          max_length=256,
          default=1, verbose_name='Type of Visit')
      visit_progress_notes = models.TextField(max_length=10000,
                                     blank=True, verbose_name='Progress Notes')
      outcomes = models.BooleanField(default=False)
  
      def __str__(self):
          return '%s %s' % (self.visit_date, self.visit_label)
  
      def get_absolute_url(self):
          return reverse('clincher:main_detail', kwargs={'pk': self.pk})
  </code></pre>
  
  <p><strong>forms.py</strong></p>
  
  <pre class="lang-py prettyprint-override"><code>class VisitForm(forms.Form):
      visit_types_list = (
          (str(1), 'Consultation'),
          (str(2), 'Procedure'),
          (str(3), 'Administrative'),)
      visit_type = forms.ChoiceField(choices=visit_types_list)
      visit_label = forms.CharField(label='Visit Label', max_length=100)
      progress_note = forms.CharField(widget=forms.Textarea)
  
      def form_valid(self, form):
          form.instance.fk_visit_user = self.request.user
          form.instance.fk_visit_main = Main.objects.get(id=self.kwargs['pk'])
          return super().form_valid(form)
  </code></pre>
  
  <p>Thus, I should end up with a child record/object that has the primary key of the parent object. </p>
  
  <p>The above code works, but I am sure that there is a simple Django-ey way of doing things much simpler, and in a robust manner. I think my solution should be found in the Django RelationshipManager, but I cannot find a solution that works. I paid a guy on Fiver, and I think he didn'y get this as simple as possible.</p>