Reputation: 4008
I have one form that appear site wide in footer. I submit this form using Ajax.
On some pages can exist also other forms.
Usually I use a CBV for create and update.
class CreateItem(CreateView):
model = Item
form_class = ItemForm
<form action="" method="post">
{% csrf_token %}
{{ form.name }}
In this case, I can't use the above. For view on submit, I have:
class FooterAddView(View):
def post(self, request):
if request.is_ajax():
.....
I need some help on the token for Ajax, and load/pass the form sitewide.
Upvotes: 1
Views: 230
Reputation: 1211
Your post() (and now I updated it with get() too) in the view Class will look like this basically:
from django.http import HttpResponseRedirect
from django.template.loader import get_template
from django.shortcuts import render
from django.views import View
from django.http import JsonResponse
from .forms import ItemForm
class FooterAddView(View):
form_class = ItemForm
# initial = {'key': 'value'}
template_name = 'myformtemplate.html'
def get(self, request, *args, **kwargs):
form = self.form_class() # you can pass the initials here too
return render(request, self.template_name, {'form2': form})
def post(self, request, *args, **kwargs):
if request.is_ajax():
form = self.form_class(request.POST)
if form.is_valid():
# <process form cleaned data>
data = form.cleaned_data
# then save
form.save()
return JsonResponse(data)
# or return HttpResponseRedirect('/success/')
else:
form = self.form_class()
print(form.errors)
# return form.errors
form = self.form_class()
return render(request, self.template_name, {'form2': form})
And you will provide the csrf token in the template file of the view(and form) like this:
templates/myformtemplate.html
<form action="#" method="post">
{% csrf_token %}
{{ form2 }}
<input type="submit" value="Submit">
</form>
I hope this can help you in your project.
And regarding the form token: the token will automatically be included in the ajax call (data: $('form').serialize(),) at form submission. More forms on one page also cannot really cause a problem in this question.
Now, I did not really understand the second part of your question first about using the created Form ’sitewide’. Then I had to understand that you maybe did not study the template system of Django deeper yet and that is why you ask that question.
So, applying this view (with the form and template) at the footer of your website:
In your application templates folder (you have to create it):
1. You have a base.html which is extendable (can also be included templates in it) with template tags like the following in the base template:
<body>
{% block content %} {% endblock content %}
{% block footer %}{% include "myformtemplate.html" %}{% endblock footer %}
</body>
You extend this base.html template with your content templates at every page.
2. And you will include the template what you create for the form in the base template’s footer block
like this simple form template in the myformtemplate.html:
<div>
<form action="#" method="post">
{% csrf_token %}
{{ form2 }}
<button type="button" name="myformbutton" id="myform2">Submit me</button>
</form>
</div>
<script>
var $j = jQuery.noConflict();
$j( document ).ready(function() {
$j('#myform2').on('click', function (e){
e.preventDefault();
$j.ajax({
type: 'POST',
url:'/newitem/', // the url that is defined in urls.py for the FooterAddView
data: $j('form').serialize(),
success: function(){
alert('created');
},
error: function(response){
alert('not submitted');
console.log(response);
}
})
})
});
</script>
And this way your template (with the above view and Form) will be at every site of your website in the footer part of your website.
Important: in order to have your form rendered in another view where you include your form template, you should define the form in that particular view too (like: form = ItemForm and in rendering part {'form2': form}. You should use 'form2' for example if you have more forms on the same page/view. And your form could be rendered in any page on the website. Otherwise you can just create your own HTML form (instead of Django rendered html form) in a form template and you can submit that form via AJAX to the targeted view from anywhere on your website. I hope you can follow the concept of this.
I hope I did not misunderstand you on this part of your questions and that’s what you wanted to ask for. If you have more questions on this of how to include a view and template ‘sitewide’, then you need to study further the Django template system ie. here (there are really endless possibilities of where you include and where you not, small views/templates): https://docs.djangoproject.com/en/2.1/ref/templates/builtins/
Upvotes: 1