How can I call multiple views in one url address in Django?
Solution 1
You can't map multiple views in one url but you can do mutiple works in one view. update your views.py as you can see that I am sending (querylist and form) both in that view
views.py
def new_measurement(request):
if request.method == "POST":
form = MeasurementForm(request.POST)
if form.is_valid():
measurement = form.save(commit=False)
measurement.measurement_date = timezone.now()
measurement.save()
else:
form = MeasurementForm()
qs = Measurement.objects.all()
context = {'form': form, 'measurement_list': qs}
return render(request, 'index.html', context)
update urls.py
from django.urls import path
from . import views
urlpatterns = [
path('', views.new_measurement, name='index'),
]
Solution 2
You can't call 2 views for one url. basically each url has to be linked to one view and that's something you can't really change.
But if you want your code to be cleaner and have multiple functions, you can call them in your view, basically what you can do is to make a view and call it when a url or even more than one url has been used and in that view decide which function to use
Example:
def god_view(request):
if request.method == "POST"
return post_func(request)
return get_func(request)
This is a very simple example but you can do so many other things.
nameisxi
Updated on March 27, 2022Comments
-
nameisxi about 2 years
I'm trying to show forms defined by new_measurement on index.html, but I only manage to get
IndexView()
to work. I tried various combinations betweenIndexView()
andnew_measurement()
, but those didn't work out at all. I know thatIndexView()
doesn't pass anything related tonew_measurement()
, andnew_measurement()
isn't called, which is the core of my problem. I'd really appreciate if someone more experienced with Django could tell me what I could, or should do. Thank you.Here's my views.py:
from django.shortcuts import render from django.utils import timezone from .models import Measurement from .forms import MeasurementForm from django.views import generic class IndexView(generic.ListView): model = Measurement context_object_name = 'measurement_list' template_name = 'index.html' queryset = Measurement.objects.all() def new_measurement(request): if request.method == "POST": form = MeasurementForm(request.POST) if form.is_valid(): measurement = form.save(commit=False) measurement.measurement_date = timezone.now() measurement.save() else: form = MeasurementForm() return render(request, 'index.html', {'form': form})
urls.py:
from django.urls import path from . import views urlpatterns = [ path('', views.IndexView.as_view(), name='index'), ]
forms.py:
class MeasurementForm(forms.ModelForm): class Meta: model = Measurement fields = ('measurement_value', 'measurement_unit')
index.html:
{% extends "base.html" %} {% block content %} <h1>Climate Measurement Tool</h1> <h2>Add a new measurement</h2> <form method="POST" class="post-form"> {% csrf_token %} {{ form.as_p }} <button type="submit" class="save">Add</button> </form> <h2>Measurements</h2> {% if measurement_list %} <ul> {% for measurement in measurement_list %} <li> <p>{{ measurement }}</p> </li> {% endfor %} </ul> {% else %} <p>No measurements yet</p> {% endif %} {% endblock %}
-
nameisxi about 6 yearsI liked this solution a lot, it's very clean, but I couldn't get it to work. I got this error when calling IndeView(): __init__() takes 1 positional argument but 2 were given. I don't understand what's wrong since it looks good to me?
-
Navid Zarepak about 6 yearsWell i don't know what your code s but it's not related to this solution. it's a simple way. if you get errors in your code you probably should check for mistakes. You're basically calling another function and returning what that function will return. Nothing complicated really.
-
Gokul nath almost 4 yearsThanks, It helps! How can I implement incase I want to use the class based view instead of function based view. Just opposite to your answer?