How to convert datefield of format mm/dd/yyyy to format dd/mm/yyyy and timefield of format 24hrs to 12hr AM/PM.
This is i am using in below circumstances
In database from a model i am getting values,so if the values getting from db is '0' the date and time format should be of (dd/mm/yyyy and 12hr AM/PM).
If the value from database field is '1',the format is of (mm/dd/yyyy and 24hr)
models.py
class Report(models.Model):
user = models.ForeignKey(User, null=False)
manual_date = models.DateField('Another date', null=True, blank=True)
manual_time = models.TimeField('Another time', null=True, blank=True)
class Settings(models.Model):
date_format = models.CharField('Date format', max_length=100)
time_format = models.CharField('Time format', max_length=100)
How to do.
Thanks
I think you are better off handling this converts at the template level using the tag date. For example, I see you pass the date and time variables to the template. Just pass them unconverted and later in the template wherever they appear do this:
{% if condition %}
{{date|date:"DATE_FORMAT"}}
{{value|time:"TIME_FORMAT"}}
{% endif %}
where "TIME_FORMAT" is the actual format that you want the date to be showed and condition is the condition that needs to be met.
If you absolutely need to do this within the view method, then you can use the module django.utils.dateformat like this:
from django.utils.dateformat import DateFormat, TimeFormat
formatted_date = DateFormat(date_variable)
formatted_date.format('Y-m-d') # substitute this format for whatever you need
formatted_time = TimeFormat(time_variable)
formatted_date.format('h') # substitute this format for whatever you need
Use that class wherever you want to format your date_variable and time_variable with the proper format string for them.
Also, about your views' code. You can't just return a string in the middle of a view method like you do:
if request.method == 'POST':
if user.date_format == '0':
date=datetime.datetime.strptime('%m/%d/%Y').strftime('%d/%m/%Y')
return date
That will throw an exception if the request method is POST. Besides, what date are you formatting there? You need to format your report.manual_date. I don't see that anywhere in the code. Apply what I said above to the variable you want to format depending on your settings and pass that variable to the tempalte_context when you return.
I hope it helps!
Related
I want to force users to input lap times into a Form using the format min:sec:millisec (e.g. 00:00:000). I also want to display these times in this format in a DetailView but I want to store them as milliseconds to calculate personal bests and lap differences.
I have tried to set the default DurationField value as 01:01:001 but it displays in the format HH:MM:SS.MS
Here is my model:
class SwimTime(models.Model):
swimmer =models.ForeignKey(Swimmer, on_delete=models.CASCADE)
time = models.DurationField(_('Time'), default= timedelta(minutes=1, seconds=1, milliseconds=1))
distance = models.PositiveIntegerField(_('Distance'),null = False, default=50)
strokeType = models.CharField(_('Stroke Type'),max_length=20, choices=strokeTypes, default='FC')
date = models.DateField(_('Date Recorded'),default = timezone.now)
def save(self, *args, **kwargs):
self.full_clean()
return super().save(*args, **kwargs)
If you want to have an "example" you can use help_text option for the field showing the expected input format. You can use it as any other option: default, null...
help_text="Please use the following format: YYYY-MM-DD."
Anyway, this has nothing to do with how it will be rendered in any template or even in database or browser validation.
For templates you can use the Datetime formatting. Django has not built-in formatting as it has for date and time, but there are some projects that solve that. Also, in this question there are some good examples for writing your own filters and load them in the template.
Also, reading your data I guess that null=False is not necessary in 'distance' field: by default it will be set to False. And keep in mind that null=True and blank=True have different uses.
---------------- EDIT --------------------
I could not succed doing it with Custom Model Field and I had to move on, so actually, I did it the alternative way specified at the end of this post.
Here is a link to a new post exposing the solution.
---------------- END EDIT --------------------
My app displays formsets where users can create objects. Once validated, the formset is displayed again and user can add new objects.
Dates should only be month and year ("%m/%Y").
I could work on the input field (though jquery) to add '01/' in front of the date entered. But after submitting, the field now displays "%d/%m/%Y" (normal).
So, I'm looking for a way to translate input string (ex : 09/2018) to dateField to store in the database, and then a translate this dateField to string when datas are retrieved from database.
I know, I could simply use a form charfield for months and another one for years.
But I would like to keep it as a date object, so, in templates, I could perform date formatting ({{ edu.start_date |date:"D, d M, Y" }})
Django custom model fields sound made for this : Django custom model fields.
I could do something like this in the custom field:
def string_to_date(value):
value = '01/' + value
la_date = datetime.strptime(value, "%d/%m/%Y").date()
return la_date
def date_to_string(la_date_date):
la_date_str = la_date_date.strftime('%m/%Y')
return la_date_str
class DateYearMonth(models.DateField):
def get_prep_value(self, value):
if value is None:
return value
return string_to_date(value)
def to_python(self, value):
if value is None:
return value
return date_to_string(value)
The form associated (i commented widgets):
class EducationForm(forms.ModelForm):
start_date = forms.CharField()
end_date = forms.CharField()
class Meta:
model = Education
exclude = ("curriculum",)
# # les widgets :
# widgets = {
# 'start_date': forms.TextInput(),
# 'end_date': forms.TextInput(),
# }
Well, this does not work so far. But I don't even know if I'm heading to the right direction...
EDIT
Actually, maybe I could use simple charfield for month and year and add a model method that would create a date out of it (maybe a #property)... This way, I would keep it simple on the form and be able to format on the templates...
You can make the Year an IntegerField and Month (CharField or Integer) and store Year in Months individually is probably the best solution.
Below is an example fore Year only(kind of DatetimeField to YearField)
import datetime
YEAR_CHOICES = []
for r in range(1980, (datetime.datetime.now().year+1)):
YEAR_CHOICES.append((r,r))
year = models.IntegerField(_('year'), choices=YEAR_CHOICES,
default=datetime.datetime.now().year)
my models.py:
class Attendancename(models.Model):
teacher_name = models.ForeignKey(Teachername)
date = models.DateField('Date')
intime = models.TimeField('IN-TIME')
outtime = models.TimeField('OUT-TIME')
my forms.py:
class AttendancenameForm(ModelForm):
teacher_name = forms.ModelChoiceType(queryset=Teachername.objects.all())
date = /*** What should I write to enforce 'DD-MM-YYY'?***/
intime = /*** to enforce 'HH:MM' format?***/
Please provide me suggestions to make it in above format otherwise, It has to raise error against entered input. How can I implement it in django forms?
I also want to calculate total hours based on intime and outtime, how can I implement it in my views.py file?
django.froms.DateField and django.forms.TimeField both have an input parameter named input_formats which is a list of date and time input formats, respectively. They define what patterns should be attempted when parsing the user input.
date = DateField(input_formats=['%d-%m-%Y'])
intime = TimeField(input_formats=['%H:%M'])
See https://docs.djangoproject.com/en/1.8/ref/forms/fields/# for details.
I'm currently working with django project. I had to filter the data store on the database based on the user input on form (at template) as looked below.
On form user either enter value or leave it blank. So what I have to do is first find the (valid) user input and then fire appropriate query to display data as user input in the form. So final result should be displayed on table at template.
As I'm new to django, how should I have to pass the data and fire query to represent data at multiple field. As help or link related to these type problem are expected. ( I just able to filter from the database with only one form and had no concept to solve this.)
Model of my temp project is as below.
class exReporter(models.Model):
first_name = models.CharField(max_length=30)
last_name = models.CharField(max_length=30)
email = models.EmailField()
gender = models.CharField(max_length=1)
age = models.IntegerField()
label = models.IntegerField()
There are a number of approaches you can take, but here is one solution you can use that involves chaining together the appropriate filters based on the form's posted data:
*Note: To conform to Python's naming convention, rename exReporter class to ExReporter.
# views.py
def process_ex_reporter_form(request):
if request.method == "POST":
# ExReporterForm implementation details not included.
ex_reporter_form = ExReporterForm(request.POST)
if ex_reporter_form.is_valid():
# If form field has no data, cleaned data should be None.
gender = ex_reporter_form.cleaned_data['gender']
age_start = ex_reporter_form.cleaned_data['age_start']
age_end = ex_reporter_form.cleaned_data['age_end']
aggregation_group = ex_reporter_form.cleaned_data['aggregation_group']
aggregation_id = ex_reporter_form.cleaned_data['aggregation_id']
ex_reporters = ExReporter.objects.get_ex_reporters(gender, age_start,
age_end, aggregation_group, aggregation_id)
else:
# Pass back form for correction.
pass
else:
# Pass new form to user.
pass
# models.py
class ExReporterManager(models.Manager):
def get_ex_reporters(self, gender, age_start, age_end, aggregation_group,
aggregation_id):
ex_reporters = super(ExReporterManager, self).get_query_set().all()
# Even though the filters are being applied in separate statements,
# database will only be hit once.
if ex_reporters:
if gender:
ex_reporters = ex_reporters.filter(gender=gender)
if age_start:
ex_reporters = ex_reporters.filter(age__gt=age_start)
if age_end:
ex_reporters = ex_reporters.filter(age__lt=age_end)
# Apply further filter logic for aggregation types supported.
return ex_reporters
Hi I have a model containing:
class MyModel(models.Model):
id = models.IntegerField(primary_key=True)
recorded_on = models.DateField()
precipitation = models.FloatField(null=True, blank=True)
I have a form which looks like this:
class QueryForm(forms.Form):
precipitation = forms.BooleanField(label=ugettext_lazy('Precipitation'),)
startdate = forms.DateField(widget = widgets.AdminDateWidget, label=ugettext_lazy('Start Date'),)
enddate = forms.DateField(widget = widgets.AdminDateWidget, label=ugettext_lazy('End Date'),)
In my views.py I have one view for the form and a separate view for collecting the data via GET. This is very simplified version of the second view.py:
def results(request):
if 'q' in request.GET:
...
startdate = request.GET.get('startdate', None)
enddate = request.GET.get('enddate', None)
data = MyModel.objects.filter(recorded_on__range = (startdate, enddate))
...
My date variables in GET are of the format 'YYYY-MM-DD'.
The problem is that the query raises this error:
coercing to Unicode: need string or buffer, datetime.date found
What is the best way to deal with my date format to make the query?
You'll need to create Date objects from your form data, which is currently a string. The error you're getting is from django trying to compare those strings to the dates on the models.
so:
from datetime import datetime
format = '%d-%m-%Y' # Or whatever your date format is
st = datetime.strptime(startdate, format)
ed = datetime.strptime(enddate, format)
data = MyModel.objects.filter(recorded_on__range=(st.date(), ed.date()))
Should point you in the right direction.
I am a bit confused about the error message (i.e. where does the error occur - when you make the query?).
However, I used this to convert a string from a url parameter to a datetime.date:
def things_by_appointment(request, appointment_date):
'''
Things with appointment date yyyy-mm-dd
'''
try:
as_date = datetime.datetime.strptime( appointment_date, '%Y-%m-%d').date
except ValueError:
return HttpResponseBadRequest('%s is not a correct date' % appointment_date )
things = Thing.objects.filter(
Q( appointment_date = as_date ),
#...
Althoug the string is from the path and not from the query string, it should not make a difference.