I have a ModelForm for a model that has a couple of files and with every file, a type description (what kind of file it is). This description field on the model has CHOICES. I have set these file uploads and description uploads as hidden fields on my form, and not required. Now the file upload is working, but the description is giving field errors, the placeholder in the dropdown is not a valid choice, it says. That's true, but since it is not required, I would like it to just be left out of the validation and I am stuck on how.
My codes, shortened them up a bit to keep it concise.
models.py
class Dog(models.Model):
FILE_TYPE_CHOICES = [
('SB', 'Stamboom'),
('RB', 'Registratiebewijs'),
('SJP', 'SJP-diploma'),
('CDD', 'CDD-diploma'),
('WT', 'Workingtestdiploma'),
('MISC', 'Overig'),
]
dog_id = models.UUIDField(unique=True, default=uuid.uuid4)
file_1 = models.FileField(upload_to=user_directory_path, blank=True, validators=[extension_validator])
desc_1 = models.CharField(choices=FILE_TYPE_CHOICES, blank=True, max_length=5)
forms.py (I excluded all these fields from the model-code above to keep it more clear, but this is to demonstrate that these fields are not required. If I print the required attribute of 'desc_1' in the view, it also says false
class DogForm(ModelForm):
class Meta:
model = Dog
fields = ('stamboomnummer', 'stamboomnaam', 'date_of_birth', 'breed',
'sex', 'sire', 'dam', 'microchip', 'breeder', 'owner',
'file_1', 'desc_1')
required = ('stamboomnummer', 'stamboomnaam', 'date_of_birth', 'breed',
'sex', 'sire', 'dam', 'microchip', 'breeder', 'owner')
widgets = {'file_1': forms.HiddenInput(),
'desc_1': forms.HiddenInput(),
}
views.py
#login_required
def newdog(request):
file_opties = Dog.FILE_TYPE_CHOICES
if request.method == 'POST':
form = DogForm(request.POST, request.FILES)
if form.is_valid():
dog = form.save(commit=False)
if request.FILES.get('file_1'):
dog.file_1 = request.FILES['file_1']
dog.user = request.user
dog.save()
assign_perm('accounts.view_dog', request.user, dog)
assign_perm('accounts.change_dog', request.user, dog)
assign_perm('accounts.delete_dog', request.user, dog)
return redirect('accounts:profile')
else:
form = DogForm()
return render(request, 'accounts/add_dog.html', {'form': form,
'buttontitle': 'Opslaan',
'formtitle': 'Hond toevoegen',
'file_type': file_opties})
My form template:
{% extends 'base.html' %}
{% load crispy_forms_tags %}
{% block title %}Title{% endblock %}
{% block content %}
<h2>{{ formtitle }}</h2>
<form id='hond' method="post" enctype="multipart/form-data">
{% csrf_token %}
{% for field in form.visible_fields %}
<div class="mb-3">
{{ field.errors }}
{{ field.label }}{% if field.field.required %}*{% endif %} <br>{{ field }}
</div>
{% endfor %}
{% if form.instance.file_1 %}
{{ form.instance.get_desc_1_display }}<br>
{% endif %}
<div class="input-group mb-3">
<input class="form-control" type="file" name="file_1" id="id_file_1">
<select class="form-select" name="desc_1" id="id_desc_1">
<option selected>Type bestand</option>
{% for item in file_type %}
<option value={{ item.0 }}>{{ item.1 }}</option>
{% endfor %}
</select>
</div>
<button class="btn btn-primary" type="submit">{{ buttontitle }}</button>
</form>
<button class="btn btn-primary" style="margin-top:20px" onclick="history.back()">Annuleren</button>
{% endblock %}
This is my form HTML, with the file input and description input right on the bottom
<form id="hond" method="post" enctype="multipart/form-data">
<input type="hidden" name="csrfmiddlewaretoken" value="gxmQEruF9vTKQshK1M4YnRRg4r0X1SkzEJwbAOwQcbq1mmGvBRSC89DwmZfT6Sv7">
<div class="mb-3">
Stamboomnummer* <br><input type="text" name="stamboomnummer" class="form-control textInput" maxlength="20" required="" id="id_stamboomnummer">
</div>
<div class="mb-3">
Stamboomnaam* <br><input type="text" name="stamboomnaam" class="form-control textInput" maxlength="60" required="" id="id_stamboomnaam">
</div>
<div class="mb-3">
Geboortedatum* <br><input type="text" name="date_of_birth" class="form-control" required="" id="id_date_of_birth">
</div>
<div class="mb-3">
Ras* <br><select name="breed" class="form-select" id="id_breed">
<option value="FR" selected="">Flatcoated Retriever</option>
<option value="CBR">Chesapeake Bay Retriever</option>
<option value="CCR">Curly Coated Retriever</option>
<option value="GR">Golden Retriever</option>
<option value="LR">Labrador Retriever</option>
<option value="NSDTR">Nova Scotia Duck Tolling Retriever</option>
<option value="MISC">Ander ras, geen retriever</option>
</select>
</div>
<div class="mb-3">
Geslacht* <br><select name="sex" class="form-select" required="" id="id_sex">
<option value="" selected="">---------</option>
<option value="REU">Reu</option>
<option value="TEEF">Teef</option>
</select>
</div>
<div class="mb-3">
Vader* <br><input type="text" name="sire" class="form-control textInput" maxlength="60" required="" id="id_sire">
</div>
<div class="mb-3">
Moeder* <br><input type="text" name="dam" class="form-control textInput" maxlength="60" required="" id="id_dam">
</div>
<div class="mb-3">
Chipnummer* <br><input type="text" name="microchip" class="form-control textInput" maxlength="30" required="" id="id_microchip">
</div>
<div class="mb-3">
Fokker* <br><input type="text" name="breeder" class="form-control textInput" maxlength="50" required="" id="id_breeder">
</div>
<div class="mb-3">
Eigenaar* <br><input type="text" name="owner" class="form-control textInput" maxlength="50" required="" id="id_owner">
</div>
<div class="input-group mb-3">
<input class="form-control" type="file" name="file_1" id="id_file_1">
<select class="form-select" name="desc_1" id="id_desc_1">
<option selected="">Type bestand</option>
<option value="SB">Stamboom</option>
<option value="RB">Registratiebewijs</option>
<option value="SJP">SJP-diploma</option>
<option value="CDD">CDD-diploma</option>
<option value="WT">Workingtestdiploma</option>
<option value="MISC">Overig</option>
</select>
</div>
<button class="btn btn-primary" type="submit">Opslaan</button>
</form>
Now, form.is_valid() is False, and the form errors are:
desc_1: Selecteer een geldige keuze. Type bestand is geen beschikbare keuze.
Which means something like: Select a valid option, Type bestand (which is the placeholder text in my form) is not a valid option.
I have tried to override the clean-function but the field is not in the cleaned_data (which is logical I guess, since it's not a valid option) and I do not know how to get in before. I think I might have to define a custom field, but I cannot seem to find how to do that on a modelform with a hidden input :/ Any help would be greatly appreciated :)
Your form is submitting desc_1, so there's a an input with name="desc_1" that has a populated value of Type bestand somewhere in your template. blank=True means the value can be left empty. Since your field has choices and blank=True, the submitted value can be either empty or one of the FILE_TYPE_CHOICES.
You're saying that Type bestand is the placeholder for this field, but if you rendered this field as a hidden input ({{ form.desc_1 }} since you have a widget overridden) it would not and should not have a placeholder.
A regular form equivalent would be:
<input type="hidden" name="desc_1" value="">
Where the value attribute is either left empty or populated with one of the existing options, nothing else.
I will also add that if you're displaying desc_1 field as a <select> element, the placeholder option's value also has to be empty.
Edit
You have an option element that is selected by default. Add the disabled attribute to stop the form from submitting the placeholder text as a value for desc_1:
<option value="" selected disabled>Type bestand</option>
The result from the code below is something like this:
Name:
Field for name
"> Email", but without the "-signs, but including the >-sign
Field for email
Why is there a "> " before "Email" and how do I remove it?
The code I am using is the following:
forms.py:
from django import forms
class ContactForm(forms.Form):
full_name = forms.CharField(required=True, max_length=100)
from_email = forms.EmailField(required=True, max_length=100)
contact.html:
{% extends "index.html" %}
{% load static %}
{% block content %}
<!-- The Contact Modal -->
<div id="contactModal" class="modal">
<!-- Modal content -->
<div class="modal-content">
<div class="container2">
<div class="row">
<div class="column">
<form method="POST">
{% csrf_token %}
<label for="name">Name:</label>
<input type="text" id="name" name="full_name" placeholder="Your name.." {{ form.full_name }}>
<label for="email">Email:</label>
<input type="text" id="email" name="from_email" placeholder="Your email.." {{ form.from_email
}}>
<input type="submit" value="Submit">
</form>
</div>
</div>
</div>
</div>
</div>
{% endblock %}
I am trying to make a website's contact page using django where client enters data and it gets submitted in database, the form gets submitted the project runs without errors and yet no data gets added in the db.
Here's my views.py file
from datetime import datetime
from firstapp.models import Contact
# Create your views here.
def index(request):
return render(request,'index.html',)
def apply(request):
return render(request,'apply.html')
def about(request):
return render(request,'about.html')
def socials(request):
return render(request,'social.html')
def contact(request):
if request.method == "POST":
name = request.POST.get("name")
email = request.POST.get("email")
subject = request.POST.get("subject")
message= request.POST.get("message")
contact=Contact(name=name,email=email,subject=subject,message=message,date=datetime.today())
contact.save
return render(request,'contact.html')
here is my contact.html
{% block title %}Contact {% endblock title %}
{% block body %}
<h2 align="center">CONTACT US </h2>
<div class="container-md">
<form method="POST" action="/contact/">
{% csrf_token %}
<div class="form-group">
<label for="exampleFormControlInput1">Name</label>
<input type="text" class="form-control" id="exampleFormControlInput1" name="name" placeholder="John Smith">
</div>
<div class="form-group">
<label for="exampleFormControlInput1">Email address</label>
<input type="email" class="form-control" id="exampleFormControlInput1" name="email" placeholder="name#example.com">
</div>
<div class="form-group">
<label for="exampleFormControlInput1">Subject</label>
<input type="text" class="form-control" id="exampleFormControlInput1" name="subject" placeholder="Business
| Suggestions | Query | Complaint | Other">
</div>
<div class="form-group">
<label for="exampleFormControlTextarea1">Message</label>
<textarea class="form-control" name="message" id="exampleFormControlTextarea1" rows="3"></textarea>
</div>
<button type="submit" class="btn btn-primary">Submit</button>
</form>
</div>
{% endblock body%}
And here's my models.py
from django.db import models
# Create your models here.
class Contact(models.Model):
name = models.CharField(max_length=50)
email =models.EmailField(max_length=254)
subject=models.CharField(max_length=10)
message=models.CharField(max_length=1000)
date=models.DateField()
As I wrote at the comments before, you have forgotten to type brackets following the save: contact.save() instead of contact.save.
It would be better and more beautiful if you do it like this:
def contact(request):
if request.method == "POST":
Contact.objects.create(**request.POST)
return render(request,'contact.html')
I have problem with my code which is i try to submit my Event form in the models. But when i run the form it will show the whole form (and another thing is that it will not show the values in the select box of the rounds) and when i click on the the submit button it will through an error.Please help me out this.
VIEW SIDE CODE:--
def addevents(request):
if request.method=="POST":
name=request.POST['events']
est=request.POST['starttime']
eet=request.POST['endtime']
s=Event()
s.ename=name
s.event_start_time=est
s.event_end_time=eet
s.save()
cats = request.POST.getlist('cats')
for i in cats:
s.categories.add(Category.objects.get(id=i))
s.save()
roundd = request.POST.getlist('rround')
for j in roundd:
s.rounds.add(Round.objects.get(id=j))
s.save()
return render(request,'adminside/addevents.html')
else:
rounds = Round.objects.all()
categories = Category.objects.all()
return render(request,'adminside/addevents.html',{'categories':categories,'rounds':rounds})
MODELS SIDE:-
class Event(models.Model):
ename=models.CharField(max_length=200)
categories = models.ManyToManyField(Category)
event_data = models.DateField()
event_start_time = models.TimeField()
event_end_time = models.TimeField()
rounds = models.ManyToManyField(Round)
EVENT PAGE FORM:-
{% extends 'adminside/master.html' %}
{% block content %}
<div class="col-12">
<div class="card">
<div class="card-body">
<h4 class="card-title">Events</h4>
<p class="card-description"> All fields are Compulsory </p>
<form class="forms-sample" method="POST">
{% csrf_token %}
<div class="form-group">
<label for="exampleInputEmail1">Add Event</label>
<input type="text" class="form-control" name="events" id="exampleInputEmail1" placeholder="Enter Event">
</div>
<div class="form-group">
<label>Categories:</label>
<select class="form-control" multiple name="cats">
{% for i in categories %}
<option value="{{ i.id }}">{{ i.cname }}</option>
{% endfor %}
</select>
</div>
<div class="form-group">
<label for="exampleInputEmail1">Event Start Time</label>
<input type="text" class="form-control" name="starttime" id="exampleInputEmail1" placeholder="Enter Event Start Time">
</div>
<div class="form-group">
<label for="exampleInputEmail1">Event End Time</label>
<input type="text" class="form-control" name="endtime" id="exampleInputEmail1" placeholder="Enter Event End Time">
</div>
<div class="form-group">
<label for="exampleInputEmail1">Round Name</label>
<select class="form-control form-control-lg" id="exampleFormControlSelect1" multiple name="rround">
{% for i in rounds %}
<option value="{{i.id}}">{{i.round}}</option>
{% endfor %}
</select>
</div>
<button type="submit" value=Addme class="btn btn-success mr-2">Submit</button>
<button class="btn btn-light">Cancel</button>
</form>
</div>
</div>
</div>
{% endblock %}
in addevents view you need to add something in event_data before saving because this value do not accept null or modify your models.py
event_data = models.DateField()
modify this to default value like the current time
event_data = models.DateField(default=timezone.now)
hope this helps
I'm trying to submit a form with just the date(and now time), but when I go to submit it I get the error incidents_incident.incident_date_time_occurred may not be NULL even when I enter an actual date in the input field. Why do I get that error when I enter in a date?
models.py
class Incident(models.Model):
incident_date_time_occurred = models.DateTimeField('incident occurred', default=timezone.now, blank=True)
class Meta:
verbose_name_plural="Incident"
forms.py
class IncidentForm(forms.ModelForm):
class Meta:
model = Incident
fields = ('incident_date_time_occurred',)
report.html
{% extends "base.html" %}
{% block content %}
<div class="container-fluid">
<form action="{% url 'incidents:report' %}" method="POST">{% csrf_token %}
{% csrf_token %}
<div class="row">
<div class="form-group col-md-4">
<label for="date" class="col-sm-4 control-label">{{ form.incident_date_time_occurred.label }}</label>
<input type="datetime-local" name= "incident_date_time_occurred" class="form-control" id="date">
</div>
</div>
<input type="submit" value="Inschrijven!" class="btn btn-primary" />
</form>
</div>
{% endblock %}
Can you check your solution by using default form created from incident? As I remember Django's dateTimeField requires two fields: date and time.
https://docs.djangoproject.com/en/1.7/ref/models/fields/#datetimefield
You are missing the name attribute on the date input. Try that:
<input type="date" class="form-control" id="date" name="incident_date_time_occurred">