Django Model Form DateTimeField form validation error - django

I am a django noobie, I am having problem with models Datetimefield. When I am using model form to fill the date time it's showing pleae enter valid date.
Here is My files
Views.py
def Report_incident(request):
if request.method=='POST':
form=IncidentReportForm(request.POST)
if form.is_valid():
report=form.save(commit=False)
report.user=request.user
report.save()
return HttpResponse('Success')
else:
form=IncidentReportForm()
context={'form':form}
return render(request, 'Assginment/report.html',context)
Here is Model Form forms.py
class DateTimeInput(forms.DateTimeInput):
input_type = 'datetime-local'
class IncidentReportForm(forms.ModelForm):
incident_cat=(
('Environmental incident','Environmental incident'),
('Injury/Illness','Injury/Illness'),
('Property Damage','Propert Damage'),
('Vehicle','Vehicle'),
)
time=forms.DateTimeField(widget=DateTimeInput(),
input_formats=['%d/%m/%Y %H:%M:%S'])
incident_type=forms.MultipleChoiceField(choices=incident_cat,
widget=forms.CheckboxSelectMultiple)
class Meta:
model=Incident
fields=('location','description','incident_location',
'severity','cause','action_taken')
Here is my Models.py part
class Incident(models.Model):
location_choices=(
('Corporate Headoffice','Corporate Headoffice'),
('Operations Department','Operations Department'),
('Work Station','Work Station'),
('Marketing Division','Marketing Division'),
)
severity_choices=(
('Mild','Mild'),
('Moderate','Moderate'),
('Severe','Severe'),
('Fatal','Fatal'),
)
location=models.CharField(choices=location_choices,max_length=300,
default='Corporate Headoffice')
description=models.TextField()
time=models.DateTimeField()
incident_location=models.CharField(max_length=200)
severity=models.CharField(max_length=200,choices=severity_choices,
default='Mild')
cause=models.TextField()
action_taken=models.TextField()
incident_type=models.CharField(max_length=200,null=True,blank=True)
reporter=models.ForeignKey(MyUser, on_delete=models.CASCADE,
related_name='reporter')
My template
{% extends "base.html" %}
{% block title %}Report An Incident {% endblock %}
{% block content %}
<form method="POST">
{{ form.as_p }}
{% csrf_token %}
<input type="submit" value="Report Incident">
</form>
<p>{{ cd }}</p>
{% if form.errors %}
{% for field in form %}
{% for error in field.errors %}
<div class="alert alert-danger">
<strong>{{ error|escape }}</strong>
</div>
{% endfor %}
{% endfor %}
{% for error in form.non_field_errors %}
<div class="alert alert-danger">
<strong>{{ error|escape }}</strong>
</div>
{% endfor %}
{% endif %}
{% endblock %}
I am guessing that the problem is in formate of date time please explain me what am I doing wrong.

Your input format at 'IncidentReportForm' is '%d/%m/%Y %H:%M:%S'.
Django database can't accept this format of a date. So, you should change 'input_formats' to '%d-%m-%Y %H:%M:%S'
I think it will work!

Related

Setting css class to field in form depending of it's type

I want to manually render login and signup forms in Django.
Here is my code:
{% load widget_tweaks %}
{% for field in form.visible_fields %}
<div class="field">
<label class="label">{{ field.label_tag }}</label>
<div class="control">
{% if form.is_bound %}
{% if field.errors %}
{% render_field field class="nice-looking-field"%}
{% for error in field.errors %}
{{ error }}
{% endfor %}
{% else %}
{% render_field field %}
{% endif %}
{% else %}
{% render_field field %}
{% endif %}
{% if field.help_text %}
<p>{{ field.help_text }}</p>
{% endif %}
</div>
</div>
{% endfor %}
{% if form.non_field_errors %}
<div class="box">
{% for error in form.non_field_errors %}
{{ error }}
{% endfor %}
</div>
{% endif %}
My question: is it possible to check in a loop what type the field has and, depending on the field, assign a specific CSS class?
For example:
Field_1 has type text, so we apply css-class-1 to it
Field_2 has a checkbox type, so we apply css-class-2 to it
you can use the django form that is inherited from modelform to define specific css class to the form fields.
for instance,
models.py file:
class Post(models.Model):
title=models.CharField(max_length=254)
text=models.TextField()
forms.py file
from . import models
class PostForm(forms.ModelForms):
class Meta():
model=models.Post
fields='__all__'
widgets={
'title':forms.TextInput(attrs={'class':'textinputclass'}), #--->> you can use this textinputclass as the css class in your css file to style the title field of your forms.
'text':forms.Textarea(attrs={'class':'content'})
}
now in your static>css>yourcss.css you can access the class that we defined above as normal css class.
.content{
font-size:15px;
}
That's all.

Django custom Auth form. How to show error messages

Another Django form question -.-
So, I have this form which works just fine, but it won't show any error messages. I'm pretty new to customising forms, so my question is that, do I need to specify anything else in order for my messages to show up?
Forms.py file
class UserLoginForm(AuthenticationForm):
error_css_class = "error"
def __init__(self,*args,**kwargs):
super(UserLoginForm, self).__init__(*args,**kwargs)
username = forms.CharField(widget=forms.TextInput(
attrs={'class': 'input','placeholder': 'Username','label':''}
))
password = forms.CharField(widget=forms.PasswordInput(
attrs={'class': 'input','placeholder': 'Password','label':''}
))
HTML File:
{%block content%}
<form class="form" method="POST">
{% csrf_token %}
<fieldset class="form-group text-center text-uppercase">
<h1 class="sign-in__header">Sign up</h1>
{% for field in form %}
<p>
{{ field }}
{{ field.help_text }}
</p>
{% endfor %}
</fieldset>
<div class="form-group">
<button class="submit" type="submit">Sign in</button>
</div>
{% for field in form %}
<div>{{ field.errors}}</div>
{% endfor %}
</div>
</form>
</div>
{%endblock content%}
If you remain on the same view when the form is not valid then in template you can access this errors by passing them to your view like this .
def View(request):
form = myForm(request.POST)
if form.is_valid():
return HttpResponseRedirect('/yourview/')
return render(request, 'template.html', {'form': form})
then in template
{% if form.errors %}
{% for field in form %}
{% for error in field.errors %}
<div class="alert alert-danger">
<strong>{{ error|escape }}</strong>
</div>
{% endfor %}
{% endfor %}
{% for error in form.non_field_errors %}
<div class="alert alert-danger">
<strong>{{ error|escape }}</strong>
</div>
{% endfor %}
{% endif %}
Try this:
{% if form.errors %}
{% for field in form %}
{% for error in field.errors %}
<p> {{ error }} </p>
{% endfor %}
{% endfor %}
{% endif %}

How to create and submit multiple instances of a form on a single page?

I want 3 instance of a URL input form so I can submit up to 3 different URLs.
forms.py
class AdditemForm(forms.Form):
url = forms.URLField(
label='Add Item',
widget=forms.URLInput(
attrs={
"class": "form-control",
}))
view.py
def ItemDetail(request, pk):
listitem = comparelist.objects.get(id=pk)
if request.method == 'POST':
form = AdditemForm(request.POST)
if form.is_valid():
url = form.cleaned_data.get("url")
items.objects.create(
link=url,
name=product_name,
price=price,
store=store,
)
return HttpResponseRedirect(request.path_info)
else:
form = AdditemForm()
template = 'itemdetail.html'
context = {
"comparelist": listitem,
"form": form,
}
return render(request, template, context)
I'm using a form snippet I found in a tutorial:
{% load widget_tweaks %}
<form method="post" class="form">
{% csrf_token %}
{% for hidden_field in form.hidden_fields %}
{{ hidden_field }}
{% endfor %}
{% if form.non_field_errors %}
<div class="alert alert-danger" role="alert">
{% for error in form.non_field_errors %}
{{ error }}
{% endfor %}
</div>
{% endif %}
{% for field in form.visible_fields %}
<div class="form-group">
{{ field.label_tag }}
{% if form.is_bound %}
{% if field.errors %}
{% render_field field class="form-control is-invalid" %}
{% for error in field.errors %}
<div class="invalid-feedback">
{{ error }}
</div>
{% endfor %}
{% else %}
{% render_field field class="form-control is-valid" %}
{% endif %}
{% else %}
{% render_field field class="form-control" %}
{% endif %}
{% if field.help_text %}
<small class="form-text text-muted">{{ field.help_text }}</small>
{% endif %}
</div>
{% endfor %}
<button type="submit" class="btn btn-primary">Submit</button>
</form>
So how do I get 3 of those forms on my page and be able to submit 3 different URLs?
I can only think of having to create 3 different form classes and paste the form snippet 3 times into the template. But that seems like a lot of unnecessary repetition.
Why "create 3 different form classes" ??? You can just create three instances of the same form.
paste the form snippet 3 times into the template
Ever heard about lists and loops ? You can put the three (or more) forms in a list and loop over it.
BUT that's actually not the best solution here - Django has Formsets for this use case.

Django returning bad help text in my signup page

As you can see the help text is not being rendered as UL instead its just plain text
Here is my code
Forms.py:
class CustomUserCreationForm(UserCreationForm):
class Meta(UserCreationForm.Meta):
model = CustomUser
now = datetime.datetime.now()
fields = ('username', 'email', 'gender', 'security_question', 'answer', 'birth_date', 'resume')
widgets={
'birth_date' :DatePickerInput(
options={
'maxDate':str(datetime.datetime.now()),
}
)
}
Views.py:
class SignUp(generic.CreateView):
form_class = CustomUserCreationForm
success_url = reverse_lazy('login')
template_name = 'users/signup.html'
signup.html:
{% extends 'base.html' %}
{% block title %}Sign Up{% endblock %}
{% block content %}
<div class="login-page">
<h1>Sign up</h1>
<form method="post" enctype="multipart/form-data">
{% csrf_token %}
<!--
{{ form.as_p }}
-->
<div class="form">
{% for field in form %}
<p>
{{ field.label_tag }}<br>
{{ field }}
{% if field.help_text %}
<small style="color: grey">{{ field.help_text }}</small>
{% endif %}
{% for error in field.errors %}
<p style="color: red">{{ error }}</p>
{% endfor %}
</p>
{% endfor %}
<button type="submit">Sign up</button>
</div>
</form>
</div>
{% endblock %}
Can someone help me figure out how do i Fix the issue ? i am using Django2.0.6
help_text is allowed to contain HTML - but you are rendering it as a safe string - you need to use the safe template filter to allow the HTML to be rendered.
You are also rendering it inside a <small> tag which will result in invalid HTML if the help text contains a list, as it does in this case.
I'd suggest you consider refactoring your template do handle this - e.g.:
{% if field.help_text %}
<div style="color: grey">{{ field.help_text|safe }}</div>
{% endif %}
You might also want to consider using styled classes instead of inline styling for these elements.
If you don't want HTML to appear in the help_text then you will need to modify the help_text of the field in question.

Django, best way to print a field key

I want to print fields of a model differently than by first_name
I want to print something like "key: value" but it prints "first_name: Georges", I would prefer that it's looks like "First name: Georges"
Currently i'm using a file named form.html that I include in every form template:
{% load widget_tweaks %}
{% for field in form %}
<div class="form-group">
{{ field.label_tag }}
{% if form.is_bound %}
{% if field.errors %}
{% render_field field class="form-control is-invalid" %}
{% for error in field.errors %}
<div class="invalid-feedback">
{{ error }}
</div>
{% endfor %}
{% else %}
{% render_field field class="form-control is-valid" %}
{% endif %}
{% else %}
{% render_field field class="form-control" %}
{% endif %}
{% if field.help_text %}
<small class="form-text text-muted">
{{ field.help_text }}
</small>
{% endif %}
</div>
{% endfor %}
And a model that looks like this:
from django.db import models
class Person(models.Model):
first_name = models.CharField(max_length=30)
last_name = models.CharField(max_length=30)
What is the best way to print first_name as "First name"?:
Is it by setting verbose_name for every fields in the models.py?
Or by setting label in the forms.py for every fields in each form?
Or by not using a dynamic template and hardcode it in my form.html?
Like what Aleksei Maide said to change that you need to alter the Label, here is an example:
in your form class add a method:
def __init__(self, *args, **kwargs):
super(YourFormName, self).__init__(*args, **kwargs)
self.fields['first_name'].label = "First name"
this is how i'm displaying it in my template:
<label class="bmd-label-static">{{ field.label }}</label>
{{ field.name }}
Think by a moment that you have a Model Form with 30 fields, and as this form, you have other 30 more Model Forms, now, you have to set every time your field labels, is a very complicated task, don't you think?
i could suggest you that use the verbose name feature to each model field and build a simple template tag that can help you to get dinamicaly the verbose name of your fields i your templates
This template tag will try to get the model field's verbose name
# yourapp/templatetags/yourapp_extras.py
from django import template
register = template.Library()
#register.simple_tag
def field_name(model, field):
field_name = field
if model:
try:
field_name = model._meta.get_field(field).verbose_name.title()
except Exception as ex:
print ex
return field_name
And in your template you can display your field label as follow
# sometemplate.html
{% load widget_tweaks %}
{% load yourapp_extras %}
{% for field in form %}
<div class="form-group">
{% field_name model field.name %} <!-- here -->
{% if form.is_bound %}
{% if field.errors %}
{% render_field field class="form-control is-invalid" %}
{% for error in field.errors %}
<div class="invalid-feedback">
{{ error }}
</div>
{% endfor %}
{% else %}
{% render_field field class="form-control is-valid" %}
{% endif %}
{% else %}
{% render_field field class="form-control" %}
{% endif %}
{% if field.help_text %}
<small class="form-text text-muted">
{{ field.help_text }}
</small>
{% endif %}
</div>
{% endfor %}