I already found many answers to that question but most of them refer to adding request.FILES wchich doesn't work for me. I can upload an image via admin page, but when it comes to form i am getting an error that image is not loaded (while it is)
Here is my model
class Player(models.Model):
name = models.CharField(max_length=30)
surname = models.CharField(max_length=30)
position = models.ForeignKey(Position,on_delete=models.CASCADE)
shirt_number = models.IntegerField()
team = models.ForeignKey(Team,null=True,on_delete=models.SET_NULL)
image = models.ImageField(upload_to='images/players/')
Here is my form
class PlayerForm(forms.ModelForm):
class Meta:
model = Player
exclude = ('team',)
Here is views.py
def team_detail(request,slug):
team = get_object_or_404(Team, slug=slug)
players = Player.objects.filter(team_id=team.id)
if request.method == "POST":
form = PlayerForm(request.POST,request.FILES)
if form.is_valid():
form.save()
return redirect('')
else:
form = PlayerForm()
return render(request,'team_detail.html',{'team':team,'players':players,'form':form})
And here is template file
<form method = "POST">
{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="SUBMIT">
</form>
Before submitting
After pressing submit button
You need to specify the enctype="…" attribute [mdn] to encode the file properly:
<form method="POST" enctype="multipart/form-data">
{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="SUBMIT">
In the view you will also need to specify a value for the Team of the instance you create:
def team_detail(request,slug):
team = get_object_or_404(Team, slug=slug)
if request.method == 'POST':
form = PlayerForm(request.POST, request.FILES)
if form.is_valid():
form.instance.team = team
form.save()
return redirect('name-of-some-view')
else:
form = PlayerForm()
players = Player.objects.filter(team=team)
return render(request,'team_detail.html', {'team':team,'players':players,'form':form})
Related
so I encountered this problem with Django and ModelForms. Everything loads as expected but when I'm trying to send data by hitting Enter nothing happens.
models.py
class Drinks(models.Model):
name = models.CharField(max_length=50)
number = models.DecimalField(decimal_places=2, max_digits=2000)
def __str__(self):
return self.name
forms.py ( I tried with list and tuple as well )
class DrinksForm(forms.ModelForm):
class Meta:
model = Drinks
fields = [
'name',
'number'
]
views.py
def DrinksView(request):
form = DrinksForm(request.POST or None)
if form.is_valid():
print("VALIDATION COMPLETE")
form.save()
form = DrinksForm()
return render (request, 'form2.html', { 'form' : form })
template.html
<form method="POST">
{% csrf_token %}
{{ form.as_p }}
</form>
admin.py
from django.contrib import admin
from .models import Drinks
admin.site.register(Drinks)
I did all necessary migrations.
Any Ideas what im doing wrong?
Your form doesn't have a submit button:
<form method="POST">
{% csrf_token %}
{{ form.as_p }}
<input type="submit" />
</form>
For your view, consider this instead:
def new_drink_view(request):
if request.method == "POST":
form = DrinksForm(request.POST)
# check if valid
# ...
else:
form = DrinksForm()
return render (request, 'form2.html', { 'form' : form })
Be sure to import the DrinksForm form.
I have a django form, but it's not showing the "upload file" field when I render it on my website. What am I doing wrong? Ideally, the form has a question ID associated with it that's submitted automatically (e.g. it doesn't have to be manually put in by the user when uploading the file)
models.py
class Choice(models.Model):
question = models.ForeignKey(Question, on_delete=models.CASCADE)
response_file = models.FileField(upload_to='audio_responses')
forms.py
class PostAudio(forms.ModelForm):
class Meta:
model = Choice
fields = ('response_file',)
views.py
def QuestionRecordSubmitView(request, pk):
model = Question
if request.method == 'POST':
form = PostAudio(request.POST, request.FILES)
if form.is_valid():
form.instance.question_id = pk
form.save()
# get survey pk
question_instance = Question.objects.get(pk=pk)
survey_pk = question_instance.survey.pk
return redirect('survey-share',pk=survey_pk)
else:
form = PostAudio()
return render(request, 'survey/question_audio_submit.html')
html
{% extends "landing/base.html" %}
{% block content %}
<h2>New Submission</h2>
<form method="POST" class="post-form" enctype="multipart/form-data">{% csrf_token %}
{{ form.as_p }}
<button type="submit" class="save btn btn-default">Save</button>
</form>
{% endblock content %}
def QuestionRecordSubmitView(request, pk):
model = Question
if request.method == 'POST':
form = PostAudio(request.POST, request.FILES)
if form.is_valid():
form.instance.question_id = pk
form.save()
# get survey pk
question_instance = Question.objects.get(pk=pk)
survey_pk = question_instance.survey.pk
return redirect('survey-share',pk=survey_pk)
else:
form = PostAudio()
return render(request, 'survey/question_audio_submit.html', {'form':form})```
I use this form for adding and updating posts. When I want to edit post and update image Django adds ['image-clear'] checkbox if post has image. But it doesn`t work. Form is not valid, if I tick checkbox and choose new image.But if I only choose new image (without tick checkbox) it works.
I was looking for a long time in what the problem, but I did not find. Can you help me? And sorry for my English
forms.py
class AddIdeaFrom(forms.ModelForm):
class Meta:
model = Idea
fields = ['title', 'description', 'image']
title = forms.CharField(max_length=500, widget=forms.TextInput(attrs={'class': 'form-control'}))
description = forms.CharField(max_length=500, widget=forms.Textarea(attrs={'class': 'form-control'}))
image = forms.FileField(required=False)
views.py
def idea_edit(request,idea_id):
if request.method == "GET":
idea = Idea.objects.get(id=idea_id)
edit_idea = AddIdeaFrom(initial={'title':idea.title,'description':idea.description,'image':idea.image})
return render(request, 'myidea/my/idea_edit.html', {'form':edit_idea, 'comment':idea.comment})
if request.method == "POST":
idea = Idea.objects.get(id=idea_id)
edit_idea = AddIdeaFrom(request.POST,request.FILES)
if edit_idea.is_valid():
edit_idea = AddIdeaFrom(request.POST, request.FILES, instance=idea)
if edit_idea.has_changed():
new_idea = edit_idea.save()
new_status = Status.objects.get(name = STATUS_REVIEW)
new_idea.status = new_status
new_idea.save()
return redirect('/')
else:
return HttpResponse('Need some changes')
else:
form = AddIdeaFrom(instance= idea)
return render(request, 'myidea/my/idea_edit.html', {'form': form})
html
<form method="post" class="post-form" enctype="multipart/form-data">
{% csrf_token %}
<label for="description.for_label" class="col-sm-9">Text</label>
{{ form.description }}
<label for="description.for_image" class="col-sm-9">Choose Image</label>
{{ form.image }}
<button type="submit" class="btn btn-space mb-">Add</button>
</div>
</form>
</div>
From your comment it looks you have problem with contradictory data in your form. It is probably because of using "Clear" checkbox with FileField widget. Try this in your forms.py:
image = forms.FileField(widget=FileInput, required=False)
This should remove "Clear" checkbox from your form.
Or if you don't want let user clear image you can unselect it in view before validation.
When I submitted forms (but on page I filled id more than 1 form) - my FormSet saves the data of only one form, the rest of the data just disappear...
My template:
<div id="data">
<form method="post" action="/lookup/" id="test_data">{% csrf_token %}
{{ formset.management_form }}
{% for form in formset %}
<section id="test_data_row">
{{ form }}
</section>
{% endfor %}
</form>
</div>
<div class="bt">
<button type="submit" class="btn btn-default" id="submit_form" form="test_data">Submit</button>
<button type="button" class="btn btn-default" id="add" value="Add row"/>Add row</button>
</div>
My forms.py:
class LookupForm(forms.ModelForm):
class Meta:
model = look
exclude = ()
LookupFormSet = formset_factory(LookupForm, can_delete=True)
My model
class look(models.Model):
class Meta():
db_table = 'lookup'
id_device = models.CharField(max_length=75)
phone_number = models.CharField(max_length=100)
phone_number_country = models.CharField(max_length=1000)
text = models.CharField(max_length=1000, default=None)
my views.py:
def manage_articles(request):
LookupFormSet = modelformset_factory(model=look, exclude=())
if request.method == "POST":
formset = LookupFormSet(
request.POST, request.FILES,
queryset=look.objects.none(),
)
if formset.is_valid():
for form in formset:
form.save()
return HttpResponseRedirect('/')
else:
formset = LookupFormSet(queryset=look.objects.none())
return render(request, 'req/lookup.html', {'formset': formset})
my JS (js for add new form):
document.getElementById('add').onclick = duplicate;
var i = 0;
var original = document.getElementById('test_data');
function duplicate() {
var clone = original.cloneNode(true); // "deep" clone
clone.id = "test_data" + ++i; // there can only be one element with an ID
original.parentNode.appendChild(clone);
}
You cannot save a formset as it contains multiple forms. So I would suggest you change your code to:
if formset.is_valid():
for form in formset:
form.save()
return HttpResponseRedirect('/')
See the docs.
I'm trying to have 2 different forms in same template. Dropdown in one of the forms is not showing any data. I've looked at other posts here but all seem to be quite overwhelming and confusing.
forms.py
class BookOnlineForm(forms.ModelForm):
patient_name = forms.CharField(max_length=250, required= True,widget=forms.TextInput())
phone = forms.CharField(max_length=200, required= True,widget=forms.TextInput())
preference = forms.ChoiceField(required=True, choices = PREFER_CHOICES, widget = forms.Select)
class Meta:
model = Booking
fields = ("patient_name","phone")
class UserContentForm(forms.ModelForm):
time = forms.ChoiceField(required=True, choices = TIME_CHOICES, widget = forms.Select)
comment = forms.CharField(max_length=2000, required= False,widget=forms.TextInput())
class Meta:
model = UserContent
fields = ("time","comment")
views.py
def showDocProfile(request, id):
try:
doctor = Doctor.objects.get(id=id)
except Doctor.DoesNotExist:
raise Http404
clinic = Clinic.objects.get(id=doctor.clinic.id)
# User content comments and like begin here
params = {}
params.update(csrf(request))
if request.user.is_authenticated():
user = request.user
# User Content Form
if request.method == "POST":
form = UserContentForm(request.POST)
if form.is_valid():
time = form.cleaned_data['time']
comment = form.cleaned_data['comment']
if request.POST.get('Like') == 'Like':
con = UserContent(time=time, comment = comment, liked = True, disliked = False, doctor_id = doctor.id, user_id = request.user.id)
con.save()
elif request.POST.get('Like') == 'Dislike':
con = UserContent(time=time, comment = comment, liked = False, disliked = True, doctor_id = doctor.id, user_id = request.user.id)
con.save()
url = '/dp/%s' % str(doctor.id)
return HttpResponseRedirect(url)
else:
form = UserContentForm()
# BookingOnline Form
if request.method == "POST":
form = BookOnlineForm(request.POST)
if form.is_valid():
patient_name = form.cleaned_data['patient_name']
preference = form.cleaned_data['preference']
phone = form.cleaned_data['phone']
lead = Booking(doctor_id=doctor.id, preference = preference, patient_name=patient_name, phone=phone)
lead.save()
url = '/dp/%s' % str(doctor.id)
return HttpResponseRedirect(url)
else:
form = BookOnlineForm()
d.update({'doctor': doctor, 'clinic': clinic,'form': form, })
return render(request, 'm1/dp.html', d)
dp.html
The usercontent form is working fine. It's just the Booking form is not showing any preferences in the dropdown menu
<form action="" method="post" id="user_uploader" > {% csrf_token %}
<input type="hidden" name="doctor" value="{{ doctor.id }}" />
<input type="text" class="form-control" placeholder="Your Name" id="patient_name" name = "patient_name">
<input type="text" class="form-control" placeholder="Your Number" id="phone" name = "phone">
<select class="form-control" id="preference" name="preference">
<option><b>Time</b></option>
{% for value, text in form.preference.field.choices %}
<option value="{{ value }}">{{ text }}</option>
{% endfor %}
</select>
{% for field in form.visible_fields %}
{{ field.errors }}
{% endfor %}
<button class="btn btn-primary" type="submit" name="submit" id="ss-submit">Submit Booking Request</button>
</form>
You should use a different name for the UserContentForm and the BookForm, instead of calling them both form.
# User Content Form
if request.method == "POST":
user_content_form = UserContentForm(request.POST)
...
else:
user_content_form = UserContentForm()
# BookingOnline Form
if request.method == "POST":
book_online_form = BookOnlineForm(request.POST)
...
# watch this indentation. In your question above it is incorrect.
else:
book_online_form = BookOnlineForm()
d.update({'doctor': doctor, 'clinic': clinic,'book_online_form': book_online_form, 'user_content_form': user_content_form})
You will have to replace form with the correct variable in the rest of the view and your template.
Ideally, you should use a prefix when including multiple forms in the same template. However, doing that will require additional changes in your template, as you have hardcoded the form fields (e.g <input ...>), instead of letting Django render them (e.g. {{ form.patient_name }}).