There are already a lot of questions+answers regarding for loops in django, but none of the solutions work for me, so there must be something fundamentally wrong.
I have a dictionary in python/json (tried both) that I want to loop through and print.
Doing the following print a new line for each character
{% for item in data.dict %}
<p>{{item}}</p>
{% endfor %}
so something like this get's printed
{
'
N
o
d
e
'
:
The following code straight up prints nothing
{% for key, values in data.dict.items %}
<p>{{key}}</p>
{% endfor %}
Data is the name of my registered model and object is one of its variables.
In my Views.py I have something similar to this:
Data.objects.create(
dict=theDictIAmPassing
}.save
EDIT
models.py
from django.db import models
class Data(models.Model):
dict1= models.TextField()
dict2 = models.TextField()
dict3 = models.TextField()
dict4 = models.TextField()
views.py
def add(request):
if request.method == 'POST':
form = EntryForm(request.POST)
if form.is_valid():
ProjectName = form.cleaned_data['ProjectName']
date = form.cleaned_data['date']
folder = form.cleaned_data['folder']
description = form.cleaned_data['description']
myprog = program.program(folder)
createMetrics(myprog)
Entry.objects.create(
ProjectName=ProjectName,
date=date,
folder=folder,
description=description
).save()
return HttpResponseRedirect('/')
else:
form = EntryForm()
return render(request, 'myApp/form.html', {'form': form})
def createMetrics(myprog):
Metrics.objects.create(
dict1=myprog.getDict1(),
dict2=myprog.getDict2(),
dict3=myprog.getDict3(),
dict4=myprog.getDict4()
).save()
Solution found at https://stackoverflow.com/a/7469287/7761401
I needed to rewrite my Data model. Textfield (which I used because I couldn't find anything else that fits) does not suit dictionary types. Instead install django-picklefield and change type to PickledObjectField
from picklefield.fields import PickledObjectField
class Data(models.Model):
dict1 = PickledObjectField()
dict2 = PickledObjectField()
dict3 = PickledObjectField()
dict4 = PickledObjectField()
Related
I have seen this approach in many web applications (e.g. when you subscribe for an insurance), but I can't find a good way to implement it in django. I have several classes in my model which inherit from a base class, and so they have several fields in common. In the create-view I want to use that inheritance, so first ask for the common fields and then ask for the specific fields, depending on the choices of the user.
Naive example, suppose I want to fill a database of places
class Place(Model):
name = models.CharField(max_length=40)
address = models.CharField(max_length=100)
class Restaurant(Place):
cuisine = models.CharField(max_length=40)
website = models.CharField(max_length=40)
class SportField(Place):
sport = models.CharField(max_length=40)
Now I would like to have a create view when there are the common fields (name and address) and then the possibility to choose the type of place (Restaurant / SportField). Once the kind of place is selected (or the user press a "Continue" button) new fields appear (I guess to make it simple the page need to reload) and the old one are still visible, already filled.
I have seen this approach many times, so I am surprised there is no standard way, or some extensions already helping with that (I have looked at Form Wizard from django-formtools, but not really linked to inheritance), also doing more complicated stuff, as having more depth in inheritance.
models.py
class Place(models.Model):
name = models.CharField(max_length=40)
address = models.CharField(max_length=100)
class Restaurant(Place):
cuisine = models.CharField(max_length=40)
website = models.CharField(max_length=40)
class SportField(Place):
sport = models.CharField(max_length=40)
forms.py
from django.db import models
from django import forms
class CustomForm(forms.Form):
CHOICES = (('restaurant', 'Restaurant'), ('sport', 'Sport'),)
name = forms.CharField(widget=forms.TextInput(attrs={'placeholder': 'Name'}))
address = forms.CharField(widget=forms.TextInput(attrs={'placeholder': 'Address'}))
type = forms.ChoiceField(
choices=CHOICES,
widget=forms.Select(attrs={'onChange':'renderForm();'}))
cuisine = forms.CharField(required=False, widget=forms.TextInput(attrs={'placeholder': 'Cuisine'}))
website = forms.CharField(required=False, widget=forms.TextInput(attrs={'placeholder': 'Website'}))
sport = forms.CharField(required=False, widget=forms.TextInput(attrs={'placeholder': 'Sport'}))
views.py
from django.http.response import HttpResponse
from .models import Restaurant, SportField
from .forms import CustomForm
from django.shortcuts import render
from django.views import View
class CustomView(View):
def get(self, request,):
form = CustomForm()
return render(request, 'home.html', {'form':form})
def post(self, request,):
data = request.POST
name = data['name']
address = data['address']
type = data['type']
if(type == 'restaurant'):
website = data['website']
cuisine = data['cuisine']
Restaurant.objects.create(
name=name, address=address, website=website, cuisine=cuisine
)
else:
sport = data['sport']
SportField.objects.create(name=name, address=address, sport=sport)
return HttpResponse("Success")
templates/home.html
<html>
<head>
<script type="text/javascript">
function renderForm() {
var type =
document.getElementById("{{form.type.auto_id}}").value;
if (type == 'restaurant') {
document.getElementById("{{form.website.auto_id}}").style.display = 'block';
document.getElementById("{{form.cuisine.auto_id}}").style.display = 'block';
document.getElementById("{{form.sport.auto_id}}").style.display = 'none';
} else {
document.getElementById("{{form.website.auto_id}}").style.display = 'none';
document.getElementById("{{form.cuisine.auto_id}}").style.display = 'none';
document.getElementById("{{form.sport.auto_id}}").style.display = 'block';
}
}
</script>
</head>
<body onload="renderForm()">
<form method="post" action="/">
{% csrf_token %}
{{form.name}}<br>
{{form.address}}<br>
{{form.type}}<br>
{{form.website}}
{{form.cuisine}}
{{form.sport}}
<input type="submit">
</form>
</body>
</html>
Add templates folder in settings.py
TEMPLATES = [
{
...
'DIRS': [os.path.join(BASE_DIR, 'templates')],
...
]
I've created a 2-page working example using modified Class Based Views.
When the form is submitted on the first page, an object of place_type is created. The user is then redirected to the second page where they can update existing details and add additional information.
No separate ModelForms are needed because the CreateView and UpdateView automatically generate the forms from the relevant object's model class.
A single template named place_form.html is required. It should render the {{ form }} tag.
# models.py
from django.db import models
from django.urls import reverse
class Place(models.Model):
"""
Each tuple in TYPE_CHOICES contains a child class name
as the first element.
"""
TYPE_CHOICES = (
('Restaurant', 'Restaurant'),
('SportField', 'Sport Field'),
)
name = models.CharField(max_length=40)
address = models.CharField(max_length=100)
place_type = models.CharField(max_length=40, blank=True, choices=TYPE_CHOICES)
def __str__(self):
return self.name
def get_absolute_url(self):
return reverse('place_update', args=[self.pk])
# Child models go here...
# urls.py
from django.urls import path
from . import views
urlpatterns = [
path('create/', views.PlaceCreateView.as_view(), name='place_create'),
path('<pk>/', views.PlaceUpdateView.as_view(), name='place_update'),
]
# views.py
from django.http import HttpResponseRedirect
from django.forms.models import construct_instance, modelform_factory
from django.views.generic.edit import CreateView, UpdateView
from django.urls import reverse_lazy
from . import models
class PlaceCreateView(CreateView):
model = models.Place
fields = '__all__'
def form_valid(self, form):
"""
If a `place_type` is selected, it is used to create an
instance of that Model and return the url.
"""
place_type = form.cleaned_data['place_type']
if place_type:
klass = getattr(models, place_type)
instance = klass()
obj = construct_instance(form, instance)
obj.save()
return HttpResponseRedirect(obj.get_absolute_url())
return super().form_valid(form)
class PlaceUpdateView(UpdateView):
fields = '__all__'
success_url = reverse_lazy('place_create')
template_name = 'place_form.html'
def get_object(self, queryset=None):
"""
If the place has a `place_type`, get that object instead.
"""
pk = self.kwargs.get(self.pk_url_kwarg)
if pk is not None:
obj = models.Place.objects.get(pk=pk)
if obj.place_type:
klass = getattr(models, obj.place_type)
obj = klass.objects.get(pk=pk)
else:
raise AttributeError(
"PlaceUpdateView must be called with an object pk in the URLconf."
)
return obj
def get_form_class(self):
"""
Remove the `place_type` field.
"""
model = self.object.__class__
return modelform_factory(model, exclude=['place_type',])
We did something similar manually, we created the views and forms based on design and did the linkage based on if conditions.
I think a nice solution would be to dynamically access subclasses of the main class and then do the necessary filtering/lists building.
UPD: I've spent some more time today on this question and made a "less raw" solution that allows to use the inheritance.
You can also check the code below deployed here. It has only one level of inheritance (as in example), though, the approach is generic enough to have multiple levels
views.py
def inheritance_view(request):
all_forms = {form.Meta.model: form for form in forms.PlaceForm.__subclasses__()}
all_forms[models.Place] = forms.PlaceForm
places = {cls._meta.verbose_name: cls for cls in models.Place.__subclasses__()}
# initiate forms with the first one
context = {
'forms': [forms.PlaceForm(request.POST)],
}
# check sub-forms selected on the forms and include their sub-forms (if any)
for f in context['forms']:
f.sub_selected = request.POST.get('{}_sub_selected'.format(f.Meta.model._meta.model_name))
if f.sub_selected:
sub_form = all_forms.get(places.get(f.sub_selected))
if sub_form not in context['forms']:
context['forms'].append(sub_form(request.POST))
# update some fields on forms to render them on the template
for f in context['forms']:
f.model_name = f.Meta.model._meta.model_name
f.sub_forms = {x.Meta.model._meta.verbose_name: x for x in f.__class__.__subclasses__()}
f.sub_options = f.sub_forms.keys() # this is for rendering selector on the form for the follow-up forms
page = loader.get_template(template)
response = HttpResponse(page.render(context, request))
return response
forms.py
class PlaceForm(forms.ModelForm):
class Meta:
model = models.Place
fields = ('name', 'address',)
class RestaurantForm(PlaceForm):
class Meta:
model = models.Restaurant
fields = ('cuisine', 'website',)
class SportFieldForm(PlaceForm):
class Meta:
model = models.SportField
fields = ('sport',)
templates/inheritance.html
<body>
{% for form in forms %}
<form method="post">
{% csrf_token %}
{{ form.as_p }}
{% if form.sub_options %}
<select class="change-place" name="{{ form.model_name }}_sub_selected">
{% for option in form.sub_options %}
<option value="{{ option }}" {% if option == form.sub_selected %}selected{% endif %}>{{ option }}</option>
{% endfor %}
</select>
{% endif %}
<button type="submit">Next</button>
</form>
{% endfor %}
</body>
What I didn't make here is saving the form to the database. But it should be rather trivial using the similar snippet:
for f in context['forms']:
if f.is_valid():
f.save()
Add a PlaceType table, and a FK, e.g. type_of_place, to the Place table:
class PlaceType(Model):
types = models.CharField(max_length=40) # sportsfield, restaurants, bodega, etc.
class Place(Model):
name = models.CharField(max_length=40)
address = models.CharField(max_length=100)
type_of_place = models.ForeignKey('PlaceType', on_delete=models.SET_NULL, null=True)
class Restaurant(Place):
cuisine = models.CharField(max_length=40)
website = models.CharField(max_length=40)
This allows you to create a new Place as either SportsField, restaurant or some other type which you can easily add in the future.
When a new place is created, you'll use the standard CreateView and Model Form. Then, you can display a second form which also uses a standard CreateView that is based on the type_of_place value. These forms can be on the same page (and with javascript on the browser side, you'll hide the second form until the first one is saved) or on separate pages--which may be more practical if you intend to have lots of extra columns. The two key points are as follows:
type_of_place determines which form, view, and model to use. For
example, if user chooses a "Sports Field" for type_of_place, then
you know to route the user off to the SportsField model form;
CreateViews are designed for creating just one object/model. When
used as intended, they are simple and easy to maintain.
There are lot of way you can handle multiple froms in django. The easiest way to use inlineformset_factory.
in your froms.py:
forms .models import your model
class ParentFrom(froms.From):
# add fields from your parent model
Restaurant = inlineformset_factory(your parent model name,Your Child model name,fields=('cuisine',# add fields from your child model),extra=1,can_delete=False,)
SportField = inlineformset_factory(your parent model name,Your Child model name,fields=('sport',# add fields from your child model),extra=1,can_delete=False,)
in your views.py
if ParentFrom.is_valid():
ParentFrom = ParentFrom.save(commit=False)
Restaurant = Restaurant(request.POST, request.FILES,) #if you want to add images or files then use request.FILES.
SportField = SportField(request.POST)
if Restaurant.is_valid() and SportField.is_valid():
ParentFrom.save()
Restaurant.save()
SportField.save()
return HttpResponseRedirect(#your redirect url)
#html
<form method="POST" enctype="multipart/form-data">
{% csrf_token %}
#{{ Restaurant.errors}} #if you want to show error
{{ Restaurant}}
{{ SportField}}
{{form}}
</form>
you can use simple JavaScript in your html for hide and show your any froms fields
Good day everyone.
I am trying to build a form which queries the database based on user data inputs and then returns the results in a new page. but I don't know exactly how to do it and I am getting errors. I've looked for a solution but couldn't find any. Please help me if you know any solutions.
Thanks in advance.
Here are my codes:
forms.py
class AttendanceForm(forms.Form):
course = forms.CharField(max_length=50)
department = forms.CharField(max_length=10)
semester = forms.IntegerField()
views.py
class AttendanceForm(generic.FormView):
form_class = CrsAttForm
template_name = 'office/crsatt_form.html'
success_url = reverse_lazy('office:members_list')
class MembersList(generic.ListView):
template_name = "office/crs_att.html"
context_object_name = 'members'
def get_queryset(self):
return Members.objects.all()
# I know I should use .filter method but how could I set the parameters to data received from the form
urls.py
url(r'^CourseAttendanceForm/$', views.AttendanceForm.as_view(), name='courseattendance'),
url(r'^CourseAttendanceForm/Results/$',views.MembersList.as_view(), name='memebrs_list'),
I think that it will be easier for you to use function based views for this one.
You can do it like this:
views.py
def form_page(request):
form = AttendanceForm()
# you get to this "if" if the form has been filled by the user
if request.method == "POST":
form = AttendanceForm(request.POST)
if form.is_valid():
course = request.POST['course']
department = request.POST['department']
semester = request.POST['semester']
members = Member.objects.filter(#here you do your filters as you already have the course, department and semester variables)
context = {'members': members}
return render(request, 'second_page.html', context)
# if the form hasn't been filled by the user you display the form
context = {'form': form}
return render(request, 'form_page.html', context)
form_page.html
<form method="post" action="{% url 'form_page' %}">
{% csrf_token %}
{{ form }}
<button type="submit">Search!</button>
</form>
urls.py
path('form_page/', views.form_page, name='form_page')
second_page.html
{% for member in members %}
# here you display whatever you want to
{% endfor %}
In a blog-ish part of my django app, editing an existing entry results in creating a new entry. It should modify the existing entry.
I have a simple model:
class BlogEntry(models.Model):
...
slug = models.SlugField(unique=True)
and a simple form for editing it:
class BlogEntryForm(forms.ModelForm):
...
slug = forms.CharField(required=False, widget=forms.HiddenInput())
class Meta:
model = BlogEntry
fields = (..., 'slug')
and the view, somewhat simplified, is also straight-forward:
class BlogEditView(View):
#method_decorator(login_required)
def get(self, request, slug=None):
context = {
'user': request.user,
}
if slug is None:
print('Creating new entry.')
context['entry'] = BlogEntryForm()
context['entry'].publication_date = datetime.datetime.now()
return render(request, 'blog/edit.html', context)
print('Using existing entry.')
entry = get_object_or_404(BlogEntry, slug=slug)
context['entry'] = BlogEntryForm(instance=entry)
return render(request, 'blog/edit.html', context)
#method_decorator(login_required)
def post(self, request):
blog_entry_form = BlogEntryForm(request.POST)
if blog_entry_form.is_valid():
blog_entry = blog_entry_form.save(commit=False)
if blog_entry.slug is None or blog_entry.slug == '':
print('New entry, slug is empty.')
blog_entry.creation_date = datetime.datetime.now()
blog_entry.slug = slugify(blog_entry.title) + '_' + hex(random.randint(0, 1e10))
blog_entry.author = request.user
blog_entry.save()
return redirect(reverse('blog/article', args=[blog_entry.slug]))
...
In get(), I confirm with the print's that I am taking the correct branch. If the entry exists, I set entry with the instance. In post(), however, I always take the new entry branch.
The layout has the typical hidden element loop.
{% for hidden in form.hidden_fields %}
{{ hidden }} hidden
{% endfor %}
though, suspiciously, when I look at the served html, I don't see the slug entry, so it's no surprise that it's not getting passed through.
Anyone see what I'm missing?
You should add the slug argument to the post() method as well. This will allow you to get the blog entry to edit from the database and pass this entry to the form as an instance argument:
#method_decorator(login_required)
def post(self, request, slug=None):
blog_entry = BlogEntry.objects.filter(slug=slug).first()
blog_entry_form = BlogEntryForm(request.POST, instance=blog_entry)
...
UPDATE: To pass the slug argument to the post() method you should use the empty action attribute of the <form> tag:
<form action="" method="POST">
In this case the form will be submitted to the url from which it was loaded. So the slug argument for the POST request will be the same as for the GET.
Merry Christmas!!!!I work with flask sqlalchemy and wtf. I could create new and would display in info.html But when I try to edit the form there is no changes in database So it is not working. So I wonder where is issues?
app.py
#With this route I can add new form in database
#app.route('/contact', methods=['GET', 'POST'])
def contact():
form = LoginForm(request.form)
if request.method == 'POST':
if form.validate()== True:
contact = Contacts()
# populate the model
form.populate_obj(contact)
db.session.add(contact)
db.session.commit()
# Contact commited to database
# RETURN TO INFO.HTML
return redirect(url_for('info'))
else:
#If the form does not have all fields that are required
return render_template('contact.html', form=form)
# This is the part for edit which is not working
# so I query and populate it but no change none in
# database none in info.html
#app.route('/edit/<int:id>', methods=['POST'])
def edit(id=None):
user = Contacts.query.get_or_404(id)
form = LoginForm(request.form,obj=user)
# check the validate and then populate the obj
if form.validate_on_submit()== True:
#populate it
form.populate_obj(user)
db.session.commit()
return redirect(url_for('info'))
else:
#If the form does not have all fields that are required
return render_template('edit.html', id=id )
#app.route('/edit/<int:id>', methods=['GET'])
def profile(id=None):
user = Contacts.query.get_or_404(id)
form = LoginForm(request.form, obj=user)
return render_template('edit.html',form=form, id =id)
# this route to html that should show all info
#app.route('/info', methods=['GET', 'POST'])
def info():
#query all
info = Contacts.query.all()
return render_template('info.html', contact=info)
model.py
# model with table name Contacts
class Contacts(db.Model):
__tablename__ = "Contacts"
id = db.Column(db.Integer, primary_key = True)
name = db.Column(db.String(50))
email = db.Column(db.String(50))
age = db.Column(db.Integer)
form.py
# this is the form wtf
Class LoginForm(Form):
name = StringField("Name", [validators.Required("Please enter your name.")])
email = StringField("Email", [validators.Required("Please enter your email address."), validators.Email("Please enter valid email address.")])
age = IntegerField("age", [validators.Required("Please enter your age.")])
submit = SubmitField("Submit")
info.html
# it should display all updated form But it wont??
{% extends "layout.html" %}
{% block content %}
<h2>show the info</h2>
{% for contact in contact %} # Maybe this is also Problem?
<strong>name:</strong> {{ contact.name}} <br>
<strong>email:</strong> {{ contact.email }} <br>
<strong>age:</strong> {{ contact.age}} <br>
<br>
{% endfor %}
{% endblock %}
You don't have to readd a Object, when you get it per query. The Queryobject is bound to the session. So you only need to commit the changes and not to add them again.
so this should be the corrected code snippet
user = Contacts.query.get_or_404(id)
form = LoginForm(request.form,obj=user)
# check the validate and then populate the obj
if form.validate()== True:
# populate it
form.populate_obj(user)
db.session.commit()
I tried your code on my machine. With little modification in code I was able to update database.
Please find updated chunk below:
#app.route('/edit/<int:id>', methods=['POST'])
def submit(id=None):
user = Contacts.query.get_or_404(id)
form = LoginForm(request.form,obj=user)
#return render_template('edit.html', form=form, id=1 )
if form.validate() == True:
form.populate_obj(user)
db.session.commit()
return redirect(url_for('info'))
else:
return redirect(url_for(edit, id=id))
#app.route('/edit/<int:id>', methods=['GET'])
def edit(id=None):
user = Contacts.query.get_or_404(id)
form = LoginForm(request.form,obj=user)
return render_template('edit.html', form=form, id=id )
I know this is an older question, but I'm referencing from Why doesn't my WTForms-JSON form update correctly?.
Essentially, you need to initialize the Form first then check to see if it was submitted or not:
form = FormBuilder()
if not form.is_submitted():
form = FormBuilder.populate_obj(obj)
else:
form = FormBuilder() # will populate from submitted data
if form.validate_on_submit():
It helped me when having the same issues.
Given the following models:
class Graph(models.Model):
owner = models.ForeignKey(User)
def __unicode__(self):
return u'%d' % self.id
class Point(models.Model):
graph = models.ForeignKey(Graph)
date = models.DateField(primary_key = True)
abs = models.FloatField(null = True)
avg = models.FloatField(null = True)
def __unicode__(self):
return u'%s' % self.date
I am trying to create a form for editing lists of Points.
The HTML input tags require additional attributes to be set, so I am using the following custom form:
class PointForm(forms.ModelForm):
graph = forms.ModelChoiceField(queryset = Graph.objects.all(),
widget = forms.HiddenInput())
date = forms.DateField(widget = forms.HiddenInput(), label = 'date')
abs = forms.FloatField(widget = forms.TextInput(
attrs = {'class': 'abs-field'}),
required = False)
class Meta:
model = Point
fields = ('graph', 'date', 'abs') # Other fields are not edited.
def pretty_date(self):
return self.data.strftime('%B')
At this point I do not know how to pass instances of the Point class to a FormSet:
def edit(request):
PointFormSet = forms.formsets.formset_factory(PointForm, extra = 0)
if request.method == 'POST':
return
# Receive 3 points to edit from the database.
graph, res = Graph.objects.get_or_create(id = 1)
one_day = datetime.timedelta(days = 1)
today = datetime.date.today()
do_edit = []
for date in [today - (x * one_day) for x in range(3)]:
point, res = Point.objects.get_or_create(graph = graph, date = date)
do_edit.append(point)
formset = PointFormSet(????) # How is this initialized with the points?
I found a hack that somewhat works, but it leads to errors later on when trying to process the resulting POST data:
do_edit = []
for date in [today - (x * one_day) for x in range(3)]:
point, res = Point.objects.get_or_create(graph = graph, date = date)
data = point.__dict__.copy()
data['graph'] = graph
do_edit.append(data)
formset = PointFormSet(initial = do_edit)
How is this done correctly?
For the reference, my template looks like this:
<form action="" method="post">
{{ formset.management_form }}
<table>
<tbody>
{% for form in formset.forms %}
<tr>
<td>{{ form.graph }} {{ form.date }} {{ form.pretty_date }}:</td>
<td width="100%">{{ form.abs }}</td>
</tr>
{% endfor %}
</tbody>
</table>
</form>
The trick is to use a "ModelFormset" instead of just a formset since they allow initialization with a queryset. The docs are here, what you do is provide a form=* when creating the model formset and queryset=* when your instantiating the formset. The form=* arguement is not well documented (had to dig around in the code a little to make sure it is actually there).
def edit(request):
PointFormSet = modelformset_factory(Point, form = PointForm)
qset = Point.objects.all() #or however your getting your Points to modify
formset = PointFormset(queryset = qset)
if request.method == 'POST':
#deal with posting the data
formset = PointFormset(request.POST)
if formset.is_valid():
#if it is not valid then the "errors" will fall through and be returned
formset.save()
return #to your redirect
context_dict = {'formset':formset,
#other context info
}
return render_to_response('your_template.html', context_dict)
So the code walks through easily. If the request is a GET then the instantiated form is returned to the user. If the request is a POST and the form is not .is_valid() then the errors "fall through" and are returned in the same template. If the request is a POST and the data is valid then the formset is saved.
Hope that helps.
-Will
If you only have one possible value which you want to set, or perhaps a closed of values, it is possible to set them after the user POSTS the data to your server using commit=False
Please consider the following code:
class UserReferralView(View):
ReferralFormSet = modelformset_factory(ReferralCode,
form=ReferralTokenForm, extra=1)
def get(self, request):
pass
def post(self, request):
referral_formset = UserUpdateView.ReferralFormSet(request.POST)
if referral_formset.is_valid():
instances = referral_formset.save(commit=False)
for instance in instances:
instance.user = request.user
instance.save()
return redirect(reverse('referrals.success_view'))
else:
return redirect(reverse('referrals.failure_view'))