Rasul Kireev
Rasul Kireev

Reputation: 429

How to render the Form (in a template tag) automatically created by CreateView

How do I render a Form automatically created by CreateView CBV?

Setup

views.py

from django.contrib.auth.mixins import LoginRequiredMixin
from django.views.generic.edit import CreateView
from .models import Journal
from django.urls import reverse



class CreateJournal(LoginRequiredMixin, CreateView):
    model = Journal
    template_name = 'journals/journal_list.html'
    fields = ('journal_name',)

    def get_success_url(self):
        return reverse('home')

    def form_valid(self, form):
        form.instance.journal_user = self.request.user
        return super(CreateJournal, self).form_valid(form)

    def get_context_data(self, **kwargs):
        context = super(CreateJournal, self).get_context_data(**kwargs)
        context['Journals'] = Journal.objects.filter(journal_user=self.request.user)
        return context

urls.py

urlpatterns = [
    path('', CreateJournal.as_view(), name='journals'),
    path('<slug:slug>', JournalEntriesList.as_view(), name='to-journal-entries'),
]

As you can see I do not have a specific form mentioned, here, that is because I don't have one. CreateView creates one automatically. As you can see, this view (which does two jobs right now, help user create an object and at the same time displays all the objects) is now rendering to 'to-journals/journal_list.html`.

I want to display the same thing (both the View and the Form) on the "home" page or any other page.

Current template tag only gets the data from the database (context)

My current attempt looks like this:

journal_tags.py

register = template.Library()

@register.inclusion_tag('template_tags/journal_list.html', takes_context=True)
def get_journals(context):
    journals = Journal.objects.filter(journal_user=context['request'].user)
    return {'journals': journals}

This successfully renders all the existing journals to any page I want. Now, how do I also render the form, that CreateView created for me.

Failed Approach

One approach I tried is to add the for argument to the function like so:

journal_tags.py

@register.inclusion_tag('template_tags/journal_list.html', takes_context=True)
def get_journals(context):
    journals = Journal.objects.filter(journal_user=context['request'].user)
    return {
        'journals': journals,
        'form': CreateJournal,
        }

This doesn't work because CreateJournal is a view and not the form. My question is how do I render the form created by class CreateJournal(LoginRequiredMixin, CreateView)?

Thanks for taking the time to look at this. I really appreciate the help of our community! Have a great day!

Upvotes: 0

Views: 350

Answers (1)

Rasul Kireev
Rasul Kireev

Reputation: 429

journal_tags.py

register = template.Library()

@register.inclusion_tag('template_tags/journal_list.html', takes_context=True)
def get_journals(context, self):
    journals = to_journal.objects.filter(journal_user=context['request'].user)
    return {
        'journals': journals,
        'form': JournalForm
        }

Where JournalForm is as ModelForm created in models.py

class JournalForm(ModelForm):
    class Meta:
        model = to_journal
        fields = ['journal_name']

Upvotes: 1

Related Questions