Klim Yadrintsev
Klim Yadrintsev

Reputation: 111

Multiple apps and views in a single html page in Django

I am relatively new to Django and do not understand it in depth. For some reason even though everyone says that Django documentation is amazing, I do not understand it what so ever.

For some reason, I am not able to integrate a model, model and a view from 2 different apps into my home.html page.

What I am trying to do is to get a newsletter sign up, as a form. It is inside jobs app Jobs also include "Jobs" which I display on the home page and blog posts which I also want to display on my HTML home page.

I do not see a need to create a new app as it's not a model which I will be reusing a lot and ready solutions are not to my liking due to limitations.

I have tried to solve what is the problem and I finally realised that it's in the url.py file under urlpatterns.

Here are my code snipets:

project url.py

from django.conf import settings
from django.contrib import admin
from django.urls import path, include
from django.conf.urls.static import static
import jobs.views
import blog.views
import compound.views
from django.conf.urls import url, include
from markdownx import urls as markdownx

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', blog.views.all_blogs_on_home, name='home'),
    path('blog/', include('blog.urls')),
    path('', include('jobs.urls')),
    path('compound/', compound.views.index),
    url(r'^markdownx/', include(markdownx))

] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

blog urls.py

from django.urls import path
from . import views
from . import models
from django.conf.urls import url

urlpatterns = [
    path('', views.allblogs, name='allblogs'),
    path('<int:blog_title>/', views.detail, name='detail'),
]

This is how I combined 2 apps together before:

blog/views.py :

def all_blogs_on_home(request, template='jobs/home.html'):
    context = {
        'blogs': Blog.objects.all().order_by('-pub_date'),
        'jobs': Job.objects.all(),
        'get_email': get_email,
    }
    return render(request, template, context)

And this what I have for my views (the only way I found to integrate newsletter without creating a new app):

jobs/views.py :

def home(request):
    jobs = Job.objects
    return render(request, 'jobs/home.html', {'jobs': jobs})


def get_email(request):
    # if this is a POST request we need to process the form data
    if request.method == 'POST':
        # create a form instance and populate it with data from the request:
        form = SignupForm(request.POST)
        # check whether it's valid:
        if form.is_valid():
            # process the data in form.cleaned_data as required
            # ...
            # redirect to a new URL:
            return HttpResponseRedirect('/email-field/')

    # if a GET (or any other method) we'll create a blank form
    else:
        form = SignupForm()

    return render(request, 'jobs/home.html', {'form': form})

In home.html I simply add this:

{{ form }}

Upvotes: 0

Views: 1484

Answers (1)

Dmitry Osipov
Dmitry Osipov

Reputation: 26

If I understand it correctly, you want to render two lists of models and a form using all_blogs_on_home view and jobs/home.html template.

To achieve that you should have something like this:

def all_blogs_on_home(request, template='jobs/home.html'):
    if request.method == 'POST':
        form = SignupForm(request.POST)
        if form.is_valid():
            # Put form handling code here
            return HttpResponseRedirect('/email-field/')

    # if a GET (or any other method) we'll create a blank form
    else:
        form = SignupForm()

    context = {
        'blogs': Blog.objects.all().order_by('-pub_date'),
        'jobs': Job.objects.all(),
        'form': form,
    }
    return render(request, template, context)

In your template jobs/home.html just render blogs and jobs as before. And you can use {{ form.as_p }} or {{ form }} to render your form. Don't forget to add /email-field/ url to one of your urls.py files.

Upvotes: 1

Related Questions