Django - rendering date field in template - django

I am working on a form which is used to stores student data. when I tried to render the form it produces an text input instead of data.
How do i render date input using django
forms.py
class StudentRegister(forms.Form):
firstname = forms.CharField(max_length= 50)
lastname = forms.CharField(max_length = 50, required=False)
mail = forms.EmailField(required=False)
dob = forms.DateField()
html
{{form.dob}}
{{form.dob.error}}

By default Django will display TextInput field, You can override your form to display DateField..
class DateInput(forms.DateInput):
input_type = 'date'
class StudentRegisterForm(ModelForm):
class Meta:
model = StudentRegister
fields = '__all__'
widgets = {
'dob': DateInput()
}

Use SelectDateWidget:
from django.forms import SelectDateWidget
# from django.forms.extras.widgets Django < 1.9
from django.utils import timezone
def past_years(ago):
this_year = timezone.now().year
return list(range(this_year, this_year - ago - 1))
class StudentRegisterForm(forms.Form):
...
dob = DateField(widget=SelectDateWidget(years=past_years(100))

Just a small correction on the previous reply by Vladimir Danilov
from django.forms import SelectDateWidget
# from django.forms.extras.widgets Django < 1.9
from django.utils import timezone
def past_years(ago):
this_year = timezone.now().year
return list(range(this_year-ago-1, this_year)) #<------- Parameters should be inverted here
class StudentRegisterForm(forms.Form):
dob = DateField(widget=SelectDateWidget(years=past_years(100))

Related

Django DateInput() widget not working in ModelForm

I'm making a user login form with a CustomUser model derived from AbstractUser, with one extra field: date_of_birth. I use CreateView to generate the form. All fields show up, the password field uses the password widget as expected (showing dots instead of characters), but the date field does not (plain character field with no formatting or calendar). What am I overlooking?
models.py:
from django.urls import reverse
from django.contrib.auth.models import AbstractUser
# Create your models here.
class CustomUser(AbstractUser):
date_of_birth = models.DateField(verbose_name="Date of Birth", blank=True, null=True)
def get_absolute_url(self):
return reverse('index')
def __str__(self):
return self.username
forms.py:
from .models import CustomUser
class CustomUserForm(forms.ModelForm):
class Meta:
model = CustomUser
fields = ["username", "password", "first_name", "last_name", "email", "date_of_birth"]
widgets = {
"password": forms.PasswordInput(),
"date_of_birth": forms.DateInput()
}
views.py:
from django.views.generic.edit import CreateView
from .models import CustomUser
from .forms import CustomUserForm
# Create your views here.
def index(request):
return HttpResponse("Hello, world")
class CustomUserCreate(CreateView):
model = CustomUser
form_class = CustomUserForm
If you come here in 2020 and beyond, just overide the default type=text undelying input by using 'type':'date'
So something like the below would work. Tested on Mozilla Dev Edition 73.+
'date_of_birth': forms.DateInput(attrs={'class':'form-control', 'type':'date'}),
Django has no built-in fancy datepicker. DateField uses the DateInput widget which is just a text input.
Thanks voodoo-burger for pointing me in the right direction. I found a video with a very simple solution to use the HTML5 datepicker: https://www.youtube.com/watch?v=I2-JYxnSiB0.
It only requires to add the following to forms.py:
class DateInput(forms.DateInput):
input_type = 'date'
and then use this as the widget (so replace forms.DateInput() with DateInput()).

How to save signed in username with the form to database? Django

All other data is saved ideally but as shown below, the user id part shows as a pull down bar and a null value which should be a signed-in username.
What's wrong with my code?
The database page
Here's my code.
views.py
from .models import Markers
from .forms import AddMarkersInfo
from django.http import HttpResponse
def addinfo(request):
if request.method == 'POST':
mks = AddMarkersInfo(request.POST)
if mks.is_valid():
submit = mks.save(commit=False)
submit.user = request.user
submit.save()
name = mks.cleaned_data['name']
address = mks.cleaned_data['address']
description = mks.cleaned_data['description']
type = mks.cleaned_data['type']
lat = mks.cleaned_data['lat']
lng = mks.cleaned_data['lng']
Markers.objects.get_or_create(name=name, address=address, description=description, type=type, lat=lat, lng=lng)
return render(request, 'home.html', {'mks': mks })
else:
mks = AddMarkersInfo()
return render(request, 'home.html', {'mks': mks})
models.py
from django.db import models
from django.contrib.auth.models import User
from django.conf import settings
from django.contrib.auth import get_user_model
def get_sentinel_user():
return get_user_model().objects.get_or_create(username='deleted')[0]
class Markers(models.Model):
User = settings.AUTH_USER_MODEL
use_id= models.ForeignKey(User, null=True, on_delete=models.SET(get_sentinel_user),)
name = models.CharField(max_length=60,default = 'name')
address = models.CharField(max_length=100,default = 'address')
description = models.CharField(max_length=150, default='description')
types = (
('m', 'museum'),
('s', 'school'),
('r', 'restaurant'),
('o', 'other'),
)
type = models.CharField(max_length=60, choices=types, default='museum')
lat = models.IntegerField()
lng = models.IntegerField()
forms.py
from django import forms
from maps.models import Markers
class AddMarkersInfo(forms.ModelForm):
class Meta:
model = Markers
fields = ['name','address','description', 'type','lat','lng',]
Well, first of all, you should remove the lines from django.contrib.auth.models import User and User = settings.AUTH_USER_MODEL in models.py if you are going to use settings.AUTH_USER_MODEL. You should use only one of the two.
And you can change your field to:
use_id= models.ForeignKey(settings.AUTH_USER_MODEL, ...
Secondly, it seems like you are duplicating the creation. The lines
submit = mks.save(commit=False)
submit.user = request.user
submit.save()
already create an Markers instance, so there is no need to call Markers.objects.get_or_create(... after that.
And, according to you models, the field should be submit.use_id instead of submit.user.
Now, if I understand your question correctly you want to make the use_id field read-only in your form/template.
I don't know why that field is even showing up in your form, since it is not listed in your forms Meta.fields.
You could try something like setting the widget attribute readonly:
class AddMarkersInfo(forms.ModelForm):
class Meta:
model = Markers
fields = ['use_id', 'name', 'address', 'description', 'type', 'lat', 'lng']
widgets = {
'use_id': forms.Textarea(attrs={'readonly': 'readonly'}),
}

Django Tables2 Filter

I am trying to display a table with filter using Django tables 2 and crispy forms.
I have the following files:
filter.py
import django_filters
from .models import Poste
class PosteFilter(django_filters.FilterSet):
id = django_filters.CharFilter(lookup_expr='icontains')
status = django_filters.CharFilter(lookup_expr='icontains')
address = django_filters.CharFilter(name='address', lookup_expr='icontains')
atualizado_em = django_filters.CharFilter(lookup_expr='icontains')
class Meta:
model = Poste
fields = {'id', 'status', 'address', 'atualizado_em',}
forms.py
from django import forms
from .models import Poste
from crispy_forms.helper import FormHelper
from crispy_forms.layout import Layout, ButtonHolder, Submit
class PosteListFormHelper(FormHelper):
model = Poste
form_tag = False
form_style = 'inline'
layout = Layout(
'id',
'status',
'address',
'atualizado_em',
Submit('submit', 'Filtrar'),
)
table.py
import django_tables2 as tables
from .models import Poste
class PosteTable(tables.Table):
class Meta:
model = Poste
# add class="paleblue" to <table> tag
attrs = {'class': 'paleblue'}
fields = ('id', 'status', 'address', 'atualizado_em')
per_page: 25
As a result, I get this:
What I want is:
exclude the word "contains" in the label
have the filter form fields inline
I tried many ways to do that without success.
It looks as if you can set the label by setting label in the CharFilter:
class PosteFilter(django_filters.FilterSet):
id = django_filters.CharFilter(lookup_expr='icontains', label='Id')
status = django_filters.CharFilter(lookup_expr='icontains', label='Status')
...
It looks as if you could also change the FILTERS_VERBOSE_LOOKUPS setting, although the docs warn that it's an advanced setting and subject to change.
from django_filters.conf import DEFAULTS
def FILTERS_VERBOSE_LOOKUPS():
verbose_lookups = DEFAULTS['VERBOSE_LOOKUPS'].copy()
verbose_lookups['icontains'] = '' # Don't add any extra text like 'contains'
return verbose_lookups
I use FormHelper to make the form inline
class UnitFilterFormHelper(FormHelper):
form_method = 'GET'
form_style = 'inline'
form_show_labels = False
label_class = 'col-md-1'
field_class = 'col-md-11'
layout = Layout(
HTML('<hr>'),
Row(
Column('branch', css_class="col-md-10"),
Column(Submit('submit', _('Apply Filter')), css_class="col-md-2"),
# css_class="form-inline",
),
)

DateField doesn't work in forms.py

I'm trying to create a date input field, but it shows as a simple input text, i'm using django 1.10, thanks in advance.
from django import forms
import datetime
from .models import Student
class StudentForm(forms.ModelForm):
class Meta:
model = Student
fields = ["name","date"]
widgets = {
'date': forms.DateInput(format="%d/%m/%Y")}

Django Exception Value: 'module' object has no attribute 'ModelsChoiceField'

my forms.py
from django import forms
from django.forms import Form
from .models import LedON, Device
class DownlinkForm(forms.Form):
Device_id = forms.ModelChoiceField(queryset = Device.objects.all() )
Time_intervall = forms.IntegerField()
Led1 = forms.ModelsChoiceField(queryset = LedON.objects.all() )
my models.py
from django.db import models
from app.models import *
from django import forms
from django.forms import ModelChoiceField
class LedON(models.Model):
Ledon = models.CharField(max_length = 50)
class Meta:
verbose_name = 'ledon'
def __str__(self):
return "%s" % (self.Ledon)
class DevEUIModelChoiceField(ModelChoiceField):
def label_from_instance(self, obj):
return obj.DevEUI
class LedonModelChoiceField(ModelChoiceField):
def label_from_instance(self, obj):
return obj.Ledon
The Device object is working and show me the ModelChoiceField.
But I don't understand why the Ledon isn't working.
If that's your actual code, you have a typo, it's ModelChoiceField, but you had ModelsChoiceField.