How to programmatically set the model when using Django CreateView?

48 views
Skip to first unread message

Robert F.

unread,
Jan 29, 2021, 1:08:44 PM1/29/21
to Django users
I am trying to programmatically set the model for a Django class-based view that inherits from CreateView and displays a form for creating a 'member' object. My problem is that  my template is not displaying the form itself. Note that I override the 'get' method to determine what model the view should use. The template page renders and I see the submit button but when I view the page's source code, the form is missing. Here's my code:

    # urls.py
    path('profile/create/', views.ProfileCreate.as_view(), name='profile-create'),

    # views.py
    class ProfileCreate(CreateView):
        model = None
        template_name = None

        def get(self, request, *args, **kwargs):
            member = Member.objects.get(user=request.user)
            if member.is_couple:
                self.model = ProfileCouple
                self.template_name = 'account/profile_couple_create.html'
                self.fields = ['person1_name', 'person2_name',
                               'person1_dob', 'person2_dob']
            else:
                self.model = ProfileSingle
                self.template_name = 'account/profile_single_create.html'
                self.fields = ['person1_name', 'person1_dob']

            context = {}
            return render(request, self.template_name, context)

    # models.py
    class ProfileSingle(models.Model):
        user = models.OneToOneField(User, on_delete=models.CASCADE, null=True)
        person1_name = models.CharField(_("Name"), max_length=50)
        person1_dob = models.DateField()

        def __str__(self):
            return self.user.username

    class ProfileCouple(models.Model):
        user = models.OneToOneField(User, on_delete=models.CASCADE, null=True)
        person1_name = models.CharField(_("Name 1"), max_length=50)
        person1_dob = models.DateField()
        person2_name = models.CharField(_("Name 2"), max_length=50)
        person2_dob = models.DateField()

        def __str__(self):
            return self.user.username

    # forms.py
    class CreateSingleProfileForm(forms.ModelForm):
        class Meta:
            model = ProfileSingle
            fields = ('user', 'person1_name', 'person1_dob')
            labels = {'user': _('Username'), 'person1_name': _(
                'Person 1 Name'), 'person1_dob': _('Person 1 DOB')}
    
    class CreateCoupleProfileForm(forms.ModelForm):
        class Meta:
            model = ProfileCouple
            ...

    # profile_single_create.html
    <div class="container mt-4">
      <h1>Create Your Profile</h1>
      <form method="post">{% csrf_token %}
          {{ form.as_p }}
          <input type="submit" value="Save">
      </form>
    </div>

    # profile_couple_create.html
    (Code similar to single template)

I know that with CBVs, Django will build the form for me.  But there will be times when I need to customize the form as I do here. What am I missing?

Arisophy

unread,
Jan 29, 2021, 5:22:48 PM1/29/21
to django...@googlegroups.com
Hi Robert

Just looking at the code
Why do you change context to empty?

context = {}
            return render(request, self.template_name, context)



Aisophy

2021年1月30日(土) 3:09 Robert F. <robert....@gmail.com>:
--
You received this message because you are subscribed to the Google Groups "Django users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to django-users...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/django-users/6d394628-6132-4927-8324-466347c8c427n%40googlegroups.com.
Reply all
Reply to author
Forward
0 new messages