My file is being uploaded in the correct path but I have an issues with it:
Whenever I refresh my HTML page the file gets uploaded again and again. How do I solve this? Also
Please help me with the code or suggest me.
Thanks in advance:)
My views.py
def about_experiment(request, ex_link_name):
researcher = None
study = None
posts = None
exp = get_object_or_404(Experiment,link_name = ex_link_name)
high_scores = ScoreItem.objects.filter(experiment=exp,active=True)
context = {
'request': request,
'exp':exp,
'high_scores': high_scores,
'awards':AwardItem.objects.filter(experiment=exp,visible=True),
}
if exp.about_file:
context['about_file'] = settings.EXPERIMENT_DIRS+exp.about_file.get_include_path()
return render(request, 'about_experiment.html', context)
if request.method == 'POST':
form = AboutHelp(request.POST, request.FILES)
posts = Help.objects.filter().order_by('-date')[0]
documents = Help.objects.all()
if form.is_valid():
obj = form.save(commit = False)
obj.save()
researcher = form.cleaned_data['researcher']
study = form.cleaned_data['study']
document = form.cleaned_data['document']
else:
form = AboutHelp()
posts = Help.objects.filter().order_by('-date')[0]
documents = Help.objects.all()
return render(request, 'about_experiment.html', {'posts': posts})
return render(request, 'about_experiment.html', {'posts': posts})
Source page
<form action="{% url 'lazer.views.about_experiment' exp.link_name %}" method="POST" name="form" enctype="multipart/form-data">
{% csrf_token %}
<label>Researcher Name(s):
<input type="text" name="researcher"><br>
<lable>Study Summary
<textarea rows="10" cols="50" placeholder="Start typing..." maxlength="500" class="form-control" name="study"></textarea>
<br>
<label>Upload your IRB approval letter:
<input type ="file" id="irb-file" class="file_input" name="document"></label>
<br>
<input type = "submit" value="Submit" class="btn btn-primary" />
</form>
destination page
<div class="tab-pane" id="irb">
<h4> List of file(s) uploaded:</h4>
<!--File upload-->
{% if documents %}
<ul>
{% for file in documents %}
<li> {{ file.document.name }} </li>
{% endfor %}
</ul>
{% else %}
<p>No such documents available.</p>
{% endif %}
<!--File upload ends-->
</div>
{% if high_scores %}
{% for hs in high_scores %}
<div class="tab-pane" id="{{ hs.link_name }}">
{% high_score request exp.link_name hs.link_name %}
</div>
{% endfor %}
{% endif %}
As #almost a beginner pointed out, you should be redirecting to some other view, if your form is submitted successfully. If not, (in your case), when the page reloads, the code for POST request is executed again. ie, your form is submitted again. I could suggest some changes in your view,
def about_experiment(request, ex_link_name):
exp = get_object_or_404(Experiment,link_name = ex_link_name)
high_scores = ScoreItem.objects.filter(experiment=exp,active=True)
context = {
'request': request,
'exp':exp,
'high_scores': high_scores,
'awards':AwardItem.objects.filter(experiment=exp,visible=True),
'posts':Help.objects.filter().order_by('-date')[0],
'documents':Help.objects.all()
}
if exp.about_file:
context['about_file'] = settings.EXPERIMENT_DIRS+exp.about_file.get_include_path()
if request.method == 'POST':
form = AboutHelp(request.POST, request.FILES)
if form.is_valid():
obj = form.save(commit = False)
obj.save()
return redirect(reverse('lazer.views.about_experiment', kwargs={ 'ex_link_name':obj.link_name }))
else:
form = AboutHelp()
return render(request, 'about_experiment.html', context)
Here, I merely assumed your obj has a field link_name. You may need to change that according to your models.
Related
My form is not saving to the database or at least i know the form is not valid i just dont know why? because it will always skip to the else in the if form.is_valid() (print("didnt work!"))
the view.py:
def index(request):
component = Component.objects.all()
form = ComponentModelForm()
if request.method == 'POST':
form = ComponentModelForm(request.POST)
if form.is_valid():
form.save()
return redirect('/maintenance')
else:
form = ComponentModelForm()
print("didnt work!")
context = {
'components': component,
'form': form,
}
return render(request, 'maintenance/index.html', context)
forms.py:
class ComponentModelForm(forms.ModelForm):
note = forms.CharField(widget=forms.Textarea)
image = forms.ImageField(error_messages = {'invalid':("Image files only")}, widget=forms.FileInput)
class Meta:
model = Component
fields = ("name",
"manufacturer",
"model",
"serial_number",
"price",
"note",
"image",
"parent",)
the template form:
{% load widget_tweaks %}
<form class="component-update-grid" enctype="multipart/form-data" method='POST' action=''>
{% csrf_token %}
<div class="component-form-data">
<span class="component-label-text">Name</span>
{% render_field form.name class="component-form-data-inputs" %}
<span class="component-label-text">Manufacturer</span>
{% render_field form.manufacturer class="component-form-data-inputs" %}
<span class="component-label-text">Model</span>
{% render_field form.model class="component-form-data-inputs" %}
<span class="component-label-text">Serial Number</span>
{% render_field form.serial_number class="component-form-data-inputs" %}
<span class="component-label-text">Price</span>
{% render_field form.price class="component-form-data-inputs" %}
<span class="component-label-text">Note</span>
{% render_field form.note class="component-form-data-inputs" %}
{% render_field form.parent class="component-form-data-inputs " %}
<input type="submit" class="button1" value='Create Component' />
</div>
<div class="component-form-img">
<img class="maintenance-component-img" src='{%static 'imgs/sidebar/logo.png'%} ' />
{% render_field form.image %}
</div>
</form>
You should not construct a new form when the form fails: a failed form will render the errors, such that the user knows what is going wrong, so:
def index(request):
component = Component.objects.all()
form = ComponentModelForm()
if request.method == 'POST':
form = ComponentModelForm(request.POST)
if form.is_valid():
form.save()
return redirect('/maintenance')
else:
# Don't create a new form!
print("didnt work!")
context = {
'components': component,
'form': form,
}
return render(request, 'maintenance/index.html', context)
I am using __init__ to build my form choices from parameters passed from the view. It looks like my choices are built correctly when I do print(choices), but the form is not loading any choices. There isn't even a widget for it showing. I do not get any errors. I've used similar code in other views which worked, which is one reason why this one is really confusing me.
I did see that print("ok") never gets printed to the shell, while print("else") does get printed
view
def newobjtoassess(request, assess_pk):
user = request.user
assessment = Assessment.objects.get(pk=assess_pk)
course_pk = assessment.course.pk
context['assessment'] = assessment
form = ObjToAssessmentForm(user=user, course_pk=course_pk)
if request.method == 'POST':
print("ok")
form = ObjToAssessmentForm(request.POST, user=user, course_pk=course_pk)
if form.is_valid():
f = form.cleaned_data
objective = f.get('objective')
assessment.objectives.add(objective)
assessment.save()
return HttpResponseRedirect(reverse('gradebook:assessupdate', args=[assess_pk]))
else:
context['form'] = form
return render(request, "gradebook/newobjtoassess.html", context)
else:
print("else")
form = ObjToAssessmentForm(user=user, course_pk=course_pk)
return render(request, "gradebook/newobjtoassess.html", context)
form
class ObjToAssessmentForm(forms.Form):
objective = forms.ChoiceField(label='Learning Objective', choices=[])
def __init__(self, *args, **kwargs):
user = kwargs.pop('user')
my_course = kwargs.pop('course_pk')
super(ObjToAssessmentForm, self).__init__(*args, **kwargs)
choices=[(o.id, str(o)) for o in Objective.objects.filter(user=user, course=my_course)]
print(choices)
self.fields['objective'] = forms.ChoiceField(choices=choices)
template
{% extends 'base-g.html' %} {% load static %} {% block content %}
{% load crispy_forms_tags %}
<div class="container">
<div class="row">
<div class="col">
<p>Course: {{ assessment.course }}</p>
</div>
</div>
<div class="row">
<div class="col">
<p>{{ assessment.assessment_name }}</p>
</div>
</div>
<div class="row">
<div class="col">
<form method="post">{% csrf_token %}
{{ form|crispy }}
<input type = "submit" value="Update">
</form>
</div>
</div>
</div>
{% endblock content %}
I got mixed up with the indentation on the else. As well, I needed to pass the form to the template in the else.
# the last (2nd of the two) else in the view above
else:
form = ObjToAssessmentForm(user=user, course_pk=course_pk)
context['form'] = form
return render(request, "gradebook/newobjtoassess.html", context)
The view can be cleaned up a bit, but this solves the problem.
I'm working on a single page site which is to have 3 different forms on the same page:
Tour form
flight form
bookform
I created the forms using model form, but how do I display the forms such that my site will know which form I'm submitting data to ?
you need pass your forms in your views.py
from your_app.forms import TourForm, FlightForm, BookForm
def your_view_name(request):
if request.method == 'POST':
tour_form = TourForm(request.POST or None)
flight_form = FlightForm(request.POST or None)
book_form = BookForm(request.POST or None)
# so you have 3 different forms
if tour_form.is_valid():
tour_form.save()
return redirect('some_url')
elif flight_form.is_valid():
flight_form.save()
return redirect('some_url')
elif book_form.is_valid():
book_form.is_save()
return redirect('some_url')
else:
return redirect('some_url')
else:
tour_form = TourForm()
flight_form = FlightForm()
book_form = BookForm()
context = {
'tour_form': tour_form,
'flight_form': flight_form,
'book_form': book_form
}
return render(request, 'your_template_name.html', context)
then simply in your template add your forms
<form method='post'>
{% csrf_token %}
{{ tour_form }}
<button class='btn btn-primary' type='submit'>submit</button>
</form>
<form method='post'>
{% csrf_token %}
{{ flight_form }}
<button class='btn btn-primary' type='submit'>submit</button>
</form>
<form method='post'>
{% csrf_token %}
{{ book_form }}
<button class='btn btn-primary' type='submit'>submit</button>
</form>
I have a situation where I display a Form sometimes and sometimes I don't display it.
Actually, there are multiple forms using the same Submit button.
What do I do to take care of the situation when a particular form is not shown in the template.
The template code
{% extends BASE_TEMPLATE %}
{% load crispy_forms_tags %}
{% block title %}<h2>New Thread</h2>{% endblock %}
{% block content %}
<div class="col-md-6">
<form method="post" accept-charset="utf-8">{% csrf_token %}
{{ threadForm|crispy }}
{{ postForm|crispy }}
{% if SHOW_WIKI %}
{{ wikiFrom|crispy }}
{% endif %}
<input type="submit" class="btn btn-primary btn-sm" value="Submit"/>
</form>
</div>
{% endblock %}
This is the view code
#login_required
def createThread(request, topic_title=None):
if topic_title:
try:
if request.method == 'POST':
topic = Topic.getTopic(topic_title)
threadForm = ThreadSUForm(request.POST, prefix='thread')
postForm = PostForm(request.POST, prefix='post')
show_wiki = getattr(settings, "REFORUMIT_ALLOW_WIKI_FOR_THREADS", False) and topic.is_wiki_allowed
wikiForm = WikiCreateForm(request.POST, prefix='wiki')
if threadForm.is_valid() and postForm.is_valid() and wikiForm.is_valid():
thread = threadForm.save(commit=False)
post = postForm.save(commit=False)
wiki = wikiForm.save(commit=False)
thread.op = post
thread.wiki_revision = None
post.setMeta(request)
wiki.setMeta(request)
if is_authenticated(request):
post.created_by = request.user
wiki.author = request.user
thread.save()
wiki.wiki_for = thread
wiki.save()
post.save()
thread.wiki_revision = wiki
thread.save()
return HttpResponseRedirect(thread.get_absolute_url)
else:
topic = Topic.getTopic(topic_title)
threadForm = ThreadSUForm(prefix='thread', initial={"topic": topic})
postForm = PostForm(prefix='post')
wikiForm = WikiCreateForm(prefix='wiki')
show_wiki = getattr(settings, "REFORUMIT_ALLOW_WIKI_FOR_THREADS", False) and topic.is_wiki_allowed
context = dict(threadForm=threadForm, postForm=postForm, wikiFrom=wikiForm, SHOW_WIKI=show_wiki)
return render(request, 'reforumit/create_thread.html', context)
except Topic.DoesNotExist:
pass
return redirect('topics')
This won't give exact answer but you can change code a bit. Providing you if conditional section only.
if threadForm.is_valid() and postForm.is_valid():
thread = threadForm.save(commit=False)
post = postForm.save(commit=False)
thread.wiki_revision = None
thread.op = post
post.setMeta(request)
if is_authenticated(request):
post.created_by = request.user
post.save()
thread.save()
if wikiForm.is_valid():
print("WikiForm is valid!")
wiki = wikiForm.save(commit=False)
print("Wiki has content")
wiki.setMeta(request)
if is_authenticated(request):
wiki.author = request.user
wiki.wiki_for = thread
wiki.save()
thread.wiki_revision = wiki
thread.save()
return HttpResponseRedirect(thread.get_absolute_url)
When I submit this form, neither are saved in the database but the HttpResponseRedirect works successfully. Any ideas why?
views.py
#login_required
def entry(request):
fantasyTeamForm = FantasySeasonForm() #Form to store each player in the fantasy team
seasonUserTournForm = PartialSeasonEntryForm()
season_tournament_id = 1
tournament_classic = Tournament(pk=season_tournament_id)
user_instance = request.user
if request.method == 'POST':
fantasyTeamForm = FantasySeasonForm(request.POST or None)
fantasyTeamForm.fields
if fantasyTeamForm.is_valid():
fantasyTeamForm.save(commit=False)
seasonUserTourn = ClassicSeasonUserList(
tournament=tournament_classic,
fantasy_team=fantasyTeamForm['FANTASY_TEAM_ID'],
user=user_instance.id,
)
seasonUserTournForm = PartialSeasonEntryForm(request.POST or None, instance=seasonUserTourn)
seasonUserTournForm.fields
if seasonUserTournForm.is_valid():
seasonUserTournForm.save()
fantasyTeamForm.save()
return HttpResponseRedirect('/season/entrysuccess') #page on success
args = {}
args.update(csrf(request))
args['form'] = fantasyTeamForm
args['form2'] = seasonUserTournForm
return render_to_response('entry.html', args, context_instance=RequestContext(request))
entry.html
<h2><b>Choose your team:</b></h2><br>
{% for field in form %}
{{field.error}}
{% endfor %}
{% for field in form2 %}
{{field.error}}
{% endfor %}
<form action="/season/entrysuccess" method="post"> {% csrf_token %}
{{form2}}
<br><br>
{{form.as_ul}}
<br>
<input type="submit" value="Submit Team" />
</form>
form action in html should have been:
<form action="/season/entry" method="post">
instead of
<form action="/season/entrysuccess" method="post">