I have a form field that I want to have as a calendar widget that defaults to the current date. I had it so it was showing the date in d/m/y format but when I'd submit it would say Enter a valid date
forms.py
class CreateBlogPostForm(forms.ModelForm):
published = forms.DateField()
class Meta:
model = BlogPost
fields = ('title', 'published','featured_image', 'post',)
widgets = {
'title': forms.TextInput(attrs={'class': 'blog-title-field', 'placeholder': 'Title'}),
'published': forms.DateInput(format=('%d-%m-%Y'), attrs={"type": 'date'}),
'post': forms.TextInput(attrs={'class': 'blog-post-field', 'placeholder': 'Write something..'}),
}
models.py
class BlogPost(models.Model):
title = models.CharField(max_length=100)
published = models.DateField()
featured_image = models.ImageField(upload_to='blog/%Y/%m/%d')
post = models.TextField()
slug = AutoSlugField(null=True, default=None,
unique=True, populate_from='title')
class Meta:
verbose_name_plural = "Blog"
def __str__(self):
return self.title
create-blog.html
{% extends 'base.html' %}
{% block content %}
<div class="container text-center">
<form enctype="multipart/form-data" method="POST">
{% csrf_token %}
{{form.title}}
{{form.post}}
{{form.featured_image}}
{{form.published}}
{{form.errors}}
<button type="submit" class="btn btn-primary"><i class="fa fa-plus" aria-hidden="true"></i> Submit</button>
</form>
</div>
{% endblock content %}
If you see carefully, your DateInput format is as format=('%d-%m-%Y') while your question states that your format for date is in d/m/y. Try with the hyphen instead of the slash, or vice versa and you should be fine.
Related
I have trouble with edit data in django project.
Everything is almost ok :) , but if I'm trying edit data my form get all data from database exept date field.
I found solution as below and I see datapicker on my edit form but I have to fill in data to this field.
Every data in edit form are filled in exept this one.
Datapicker for adding records works good. I'm using the same form to add and edit.
My forms.py is listed below:
from django import forms
from .models import Expens, Category
class DateInput(forms.DateInput):
input_type = 'date'
class ExpensForm(forms.ModelForm):
class Meta:
model = Expens
fields = ('name', 'date', 'category', 'value', 'add_description', 'scan')
labels = {
'name': 'Nam:',
'date': 'Date:',
'category': 'Category:',
'value': 'Value:',
'add_description': 'Descripion:',
'scan': 'Scan:',
}
widgets ={
'name': forms.TextInput(attrs={'class': 'form-control'}),
'date': DateInput(attrs={'class': 'form-control'}),
'category': forms.Select(attrs={'class': 'form-control'}),
'value': forms.NumberInput(attrs={'class': 'form-control'}),
'add_description': forms.TextInput(attrs={'class': 'form-control'}),
'scan':(),
}
My html template to this forms is listed below:
{% extends 'expenses/index.html' %}
{% block tytul %} DATABASE FORMS {% endblock %}
{% load bootstrap5 %}
{{ form.media }}
{% block strona %}
{% if new %}
<h5>Add record</h5>
{% else %}
<h5>Edit record</h5>
{% endif %}
<div class="mb-3">
<form method="post" enctype="multipart/form-data">
{% csrf_token %}
{% bootstrap_form form %}
<div class="col-lg-12" style="text-align:center">
{% if new %}
<button type="submit" class="btn btn-success btn-sm">ADD</button>
{% else %}
<button type="submit" class="btn btn-success btn-sm">EDIT</button>
{% endif %}
</div>
</form>
</div>
<div class="col-lg-12" style="text-align:center">
<br>
<br>
Back
</div>
{% endblock %}
My models.py listing is:
from django.db import models
# Create your models here.
class Category(models.Model):
name = models.CharField(max_length=60, blank=False, unique=True)
add_description = models.TextField(default="")
def __str__(self):
return self.name
class Expens(models.Model):
name = models.CharField(max_length=120, blank=False, null=False)
date = models.DateField(null=True, blank= True)
category= models.ForeignKey(Category, blank=False, null=True, on_delete=models.SET_NULL)
value = models.DecimalField(max_digits=10, decimal_places=2, null = False, blank=False)
add_description = models.TextField(default="", null=True, blank=True)
scan = models.ImageField(upload_to ="scans", null = True, blank = True)
def __str__(self):
return self.expens_with_data()
def expens_with_data(self):
return "{} ({})".format(self.category, self.date)
What is wrong with my form ? :)
I have a date of birth field in my model but why it's not showing up in the template when I render it? The date_of_birth is inside Teacher model. And Do you have any good idea on date_of_birth field? Because right now I'm using charfield for that so I need to convert the DateInput to string so that I can add it into charfield.
here is my models.py
class Teacher(models.Model):
user = models.OneToOneField(CustomUser, on_delete=models.CASCADE, primary_key=True)
date_of_birth = models.CharField(max_length=100)
teacher_type = models.CharField(max_length=50
def __str__(self):
return self.user.email
my forms.py
class TeacherRegisterForm(UserCreationForm):
date_attr = {'class': 'form-control', 'id': 'dateofbirth-register', 'type': 'date'}
date_of_birth = forms.DateField(widget = forms.DateInput(attrs=date_attr))
teacher_type = forms.ChoiceField(label=_('Teacher Type'), choices=type_choice
class Meta(UserCreationForm):
model = CustomUser
fields = ['date_of_birth', 'teacher_type']
def save(self, commit=True):
user = super().save(commit=False)
user.is_teacher = True
user.save()
teacher = Teacher.objects.create(user=user)
teacher.date_of_birth += str(self.cleaned_data.get('date_of_birth'))
teacher.teacher_type += self.cleaned_data.get('teacher_type')
return user
views.py
#login_required
#teacher_required
def teacherInfoView(request):
template_name = "attendance/content/teacher/teacher_info.html"
teacher_info = Teacher.objects.filter(user=request.user)
context = {'teacher_info': teacher_info}
return render(request, template_name, context)
template
{% for info in teacher_info %}
<!-- firstname -->
<div class="row">
<div class="ml-5 mr-auto">
<h5>Name : {{ info.user.first_name }} {{ info.user.last_name }}</h5>
</div>
<div class="ml-5">
<h5>Email : {{ info.user.email }}</h5>
</div>
</div>
<div class="row">
<div class="ml-5">
<h5>Date Of Birth : {{ info.date_of_birth }}</h5>
</div>
<div class="ml-5">
<h5>Gender : {{ info.user.gender }}</h5>
</div>
</div>
{% endfor %}
I am struggling with Django forms.
I have the following model.py:
class Property(models.Model):
portfolio = models.ForeignKey("portfolios.Portfolio", on_delete=models.CASCADE)
class PropertyImage(models.Model):
property = models.ForeignKey("Property", on_delete=models.CASCADE)
image = models.ImageField(upload_to = property_image_upload_to)
def __str__(self):
return self.image.url
class PropertyDocument(models.Model):
property = models.ForeignKey("Property", on_delete=models.CASCADE)
document = models.FileField()
class Address(models.Model):
property = models.OneToOneField("Property", on_delete=models.CASCADE)
line1 = models.CharField(max_length=100)
line2 = models.CharField(max_length=100, null=True, blank=True)
line3 = models.CharField(max_length=100, null=True, blank=True)
post_code = models.CharField(max_length=7)
town = models.CharField(max_length=100, null=True, blank=True)
city = models.CharField(max_length=100)
When adding/updating a property, I want the form to show the form for related objects like the address, documents/images instead of the select list's that appear in forms - I want to be able to add/edit the related data.
My view.py file
class PropertyCreate(CreateView):
model = Property
form_class=PropertyAddressFormSet
success_url = reverse_lazy('Property_list')
def get_context_data(self, **kwargs):
data = super(PropertyCreate, self).get_context_data(**kwargs)
return data
Property_form.html
{% extends 'base/base.html' %}
{% load crispy_forms_tags %}
{% block content %}
<form method="post">{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="Submit" class="btn btn-primary" />
<button class="btn btn-link" onclick="javascript:history.back();">Cancel</button>
</form>
{% endblock %}
urls.py
from . import views
app_name = 'properties'
urlpatterns = [
path('<int:portfolio_id>/<int:pk>/edit', views.PropertyUpdate.as_view(), name='property_edit'),
path('<int:portfolio_id>/create', views.PropertyCreate.as_view(), name='property_new'),
]
I've read about inlineformset_factories and inlineformset's etc, but is this the best choice for my scenario? If so, I can't figure out how to show the portfolio, address form
I;m currently using a inlineformset like so, which creates the Address form on the PropertyCreate view, but I want to also add in the PropertyImages and PropertyDocs to the ProertyCreate view.:
PropertyAddressFormSet = inlineformset_factory(
parent_model=Property,
model=Address,
form=AddressForm,
extra=0,
min_num=1
)
For anyone in the same boat as me, I managed to get this working with the following code:
Forms.py:
class PropertyForm(ModelForm):
""" Edit a property """
class Meta:
model = Property
exclude = ()
PropertyAddressFormSet = inlineformset_factory(
parent_model=Property,
model=Address,
form=AddressForm,
extra=0,
min_num=1
)
Views.py
class PropertyCreate(CreateView):
model = Property
form_class=PropertyForm
success_url = reverse_lazy('Property_list')
def get_context_data(self, **kwargs):
data = super(PropertyCreate, self).get_context_data(**kwargs)
if self.request.POST:
data['address'] = PropertyAddressFormSet (self.request.POST, instance=self.object)
else:
data['address'] = PropertyAddressFormSet ()
return data
template:
<form method="post" enctype="multipart/form-data">
{% csrf_token %}
{{ form |crispy }}
<fieldset class="border p-2">
<legend class="w-auto">Address</legend>
{{ address.management_form }}
{% for form in address.forms %}
<div >
{{ form.as_p }}
</div>
{% endfor %}
</fieldset>
</form>
Hope this helps someone.
I am working with this simple form and can't able to display inline validation in each line. I want validation as it worked in the Django admin site, with particular fields. How could it be done! It only shows the HTML validation like "Please fill out the field"
models.py
class MemberRegistration(models.Model):
name = models.CharField(max_length=100)
email = models.EmailField(max_length=100)
phone = models.CharField(max_length=50)
def __str__(self):
return self.name
forms.py
from django import forms
from . models import MemberRegistration
from django.core import validators
class MemberForm(forms.ModelForm):
name = forms.CharField(widget=forms.TextInput(
attrs={'class': 'form-control', 'placeholder':'Name'}),
max_length=100, error_messages = {
'required':"Please Enter your Name"})
email = forms.EmailField(widget=forms.EmailInput(
attrs={'class': 'form-control', 'placeholder':'E-mail'}),
required=True, max_length=100)
phone = forms.CharField(widget=forms.TextInput(
attrs={'class': 'form-control', 'placeholder':'Phone'}),
required=True, max_length=100)
class Meta:
model = MemberRegistration
fields = "__all__"
def clean_name(self):
all_clean_data = super().clean()
name = all_clean_data['name']
if name == "":
raise forms.ValidationError("Name field is required")
member_form.html:
{% block body_block %}
<div class="container">
<h1>This is member reg form</h1>
<form method="post" novalidate>
{% csrf_token %}
<div class="form-group">
<label for="">Name</label>
{{ form.name.errors }}
{{form.name}}
</div>
<div class="form-group">
<label for="">Email</label>
{{ form.email.errors }}
{{form.email}}
</div>
<div class="form-group">
<label for="">Phone</label>
{{form.phone}}
</div>
<button type="submit" class="btn btn-primary">Submit</button>
</form>
</div>
{% endblock %}
How I can do this with Django's built-in validation?
I'm getting an issue with my Django form validation. I would like to display form errors and make all fields required. I don't know why my fields can accept blank while blank is not defined in my model file.
This is my model :
class Customer(models.Model):
email = models.CharField(max_length=150, verbose_name=_('e-mail'), null=False)
first_name = models.CharField(max_length=70, verbose_name=_('first name'), null=False)
last_name = models.CharField(max_length=70, verbose_name=_('last name'), null=False)
country = models.ForeignKey(Country, verbose_name=_('country'))
institution = models.CharField(max_length=255, verbose_name=_('institution'), null=True)
creation_date = models.DateTimeField(auto_now_add=True, verbose_name=_('creation date'), null=False)
modification_date = models.DateTimeField(auto_now=True, verbose_name=_('modification date'), null=False)
class Meta:
verbose_name = _('customer')
verbose_name_plural = _('customer')
def __str__(self):
return f"{self.email}"
This is my form :
class CustomerForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
super(CustomerForm, self).__init__(*args, **kwargs)
self.fields['country'].empty_label = _('Select a country')
self.fields['country'].queryset = self.fields['country'].queryset.order_by(
'name')
for key in self.fields:
self.fields[key].required = True
class Meta:
model = Customer
fields = ['email', 'first_name', 'last_name', 'country', 'institution']
widgets = {
'email': forms.TextInput(attrs={'placeholder': _('name#example.com')}),
'first_name': forms.TextInput(attrs={'placeholder': _('First Name')}),
'last_name': forms.TextInput(attrs={'placeholder': _('Last Name')}),
'institution': forms.TextInput(attrs={'placeholder': _('Agency, company, academic or other affiliation')}),
}
You can find here my view with Django CBV :
class HomeView(CreateView):
""" Render the home page """
template_name = 'app/index.html'
form_class = CustomerForm
def get_context_data(self, **kwargs):
kwargs['document_list'] = Document.objects.all().order_by('publication__category__name')
return super(HomeView, self).get_context_data(**kwargs)
def post(self, request, *args, **kwargs):
if request.method != 'POST':
return HttpResponseRedirect(self.get_success_url())
form = self.form_class(request.POST)
email = request.POST['email']
country_id = request.POST['country']
country = Country.objects.get(id=country_id)
for checkbox in request.POST.getlist('DocumentChoice'):
document = Document.objects.get(id=checkbox)
token = self.gen_token(email, document.edqm_id)
Download.objects.create(email=email, country=country, pub_id=checkbox, token=token,
expiration_date=now + timedelta(minutes=10))
if not form.is_valid():
print('form invalid')
continue
return HttpResponseRedirect(self.get_success_url())
And finally my template :
{% extends "publication/base_backend.html" %}
{% load staticfiles %}
{% load i18n %}
{% load crispy_forms_tags %}
{% block main %}
<form method="post" id="customerform" novalidate>
{% csrf_token %}
<h3>{% trans 'Your information' %}</h3>
<hr>
<div class="col-sm-12 col-md-12 col-lg-12">
{{ form.email|as_crispy_field:"bootstrap" }}
</div>
<br />
<br />
<br />
<br />
<div class="alert alert-info col-sm-12 col-md-12 col-lg-12" role="alert">
<small>{% trans "The fields below are optional if you have already requested a publication:" %}</small>
</div>
<div class="col-sm-5 col-md-5 col-lg-5">
{{ form.first_name|as_crispy_field:"bootstrap" }}<br>
{{ form.country|as_crispy_field:"bootstrap" }}
</div>
<div class="col-sm-5 col-md-5 col-lg-5 col-sm-offset-2 col-md-offset-2 col-lg-offset-2">
{{ form.last_name|as_crispy_field:"bootstrap" }}<br>
{{ form.institution|as_crispy_field:"bootstrap" }}
</div>
<div class="col-md-12">
<br />
<br />
</div>
<input type="submit" class="btn btn-default" value="{% trans 'Save' %}"/>
{% trans 'Cancel' %}
</form>
Issues :
According to required fields, I don't know why my form doesn't display missing values errors when I want to submit it.
I have to display fields as shown in my template because I have to make bootstrap design.
In order to display form errors, I have to write {{form.email.errors}} for example but nothing appears.
Thank you by advance