Git Product home page Git Product logo

django-date-extensions's Introduction

django-date-extensions
by Matthew Somerville

This code adds a few small extensions to Django's DateField, to handle both
approximate dates (e.g. "March 1963") and default year dates (e.g. assume
"24th June" is the most recent such).

example contains a hopefully self-contained Django project that simply shows
off a form with these methods of entry.

Approximate dates
=================

A new object, ApproximateDate, is used to represent dates that might not have a
month or a day. ApproximateDateField is the model field used to represent these
objects in a Model, and ApproximateDateFormField is the field used in a Django
form. Everything should work seamlessly simply by specifying a model field as
ApproximateDateField rather than DateField.

Default year dates
==================

PrettyDateField is a form field to be used on DateField model fields. It takes
one argument, future, which is a nullable boolean. If True, a date input that
is missing a year will be taken to be the next possible occurrence of that date
- e.g. on 24th November 2009, entering 24th December will be taken to be
2009-12-24, whilst entering 3rd March will be taken to be 2010-03-03. If future
is False, the reverse occurs, with year-less dates being assumed to be the
closest occurrence of that date in the past.

If future is not set, then PrettyDateField acts the same as a DateField, only
allows suffixes on ordinals, and assumes D/M/Y rather than M/D/Y. 

Testing
=======
Run 'tox' with tox installed.

Todo
====

Improve date parsing to take more inputs like my traintimes.org.uk PHP, such as
"next Friday".


Any queries or comments, do get in touch. Something's probably broken, as I tried
to tidy up the code a little for public release :)

Matthew Somerville.

django-date-extensions's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

django-date-extensions's Issues

RemovedInDjango30Warning: Context parameter in ApproximateDateField.from_db_value()

I am incrementally upgrading an old site to the latest version of Django, and right now with Django 2.1 and 2.2 installed, I am getting an error every time I test display of a page that uses ApproximateDateField:

WARNING:py.warnings:~/.virtualenvs/[my-env]/lib/python3.7/site-packages/django/db/models/sql/compiler.py:1072: RemovedInDjango30Warning: Remove the context parameter from ApproximateDateField.from_db_value(). Support for it will be removed in Django 3.0.
  RemovedInDjango30Warning,

It seems like though it's an argument in the method (default to None), the context isn't actually used in the method.

I'm about to upgrade the site to Django 3.0 next. Is this an issue that you might address, or is this user error on my end? Thanks.

CommandError: Unable to serialize database: 'ApproximateDateField' object has no attribute '_get_val_from_obj'

When I try to serialize my development database into a fixture with the command:

$ python manage.py dumpdata --indent 4

I get the following traceback:

CommandError: Unable to serialize database: 'ApproximateDateField' object has no attribute '_get_val_from_obj'
Exception ignored in: <generator object cursor_iter at 0x7fd5723027b0>
Traceback (most recent call last):
  File "/home/jonancm/.cache/pypoetry/virtualenvs/gamehunter-gvZjkORE-py3.8/lib/python3.8/site-packages/django/db/models/sql/compiler.py", line 1609, in cursor_iter
    cursor.close()
sqlite3.ProgrammingError: Cannot operate on a closed database.

I'm using the following software versions:

  • django-date-extensions 3.1
  • Django 3.1.4
  • Python 3.8.5

Doing a quick research, I found a Django ticket that deprecates this method.

In the Django documentation on how to write custom model fields, I found that you should use the method value_from_object to implement the method value_to_string.

As of now, django-date-extensions implements ApproximateDateField.value_to_string relying on Field._get_val_from_obj:

value = self._get_val_from_obj(obj)

In the aforementioned ticket, you can see the Field._get_val_from_obj method was deprecated because it duplicates the functionality of Field.value_from_object.

I haven't found any other uses of value_from_object in the codebase, so the solution should be fairly easy: just replace value_from_object with value_from_object in line 155 of fields.py.

I will try this and submit a pull request if I manage to solve the issue.

Output Date Format

There does not seem to be a way to keep / specify the format you want the widget to output.
For example if I put "01/05" and save the object and then retrieve it again it displays as "5th January". I would like a way to say display as "01/05".

__unicode__ method for ApproximateDate class

Hi guys,

I ran into a UnicodeEncodeError ('ascii' codec can't encode characters in position 0-5: ordinal not in range(128), The string that could not be encoded/decoded was: Январь 1996) when rendering a template using django-date-extensions ApproximateDateField together with djangos built-in i18n translation framework (languages English and Russian).

Turns out that a missing unicode method for the ApproximateDate class seems to be responsible as renaming the str method (line 47 in fields.py) to unicode fixed the problem.

Maybe you could consider adding it upstream.

Great thanks for the very useful extension package, you saved me a lot of time and trouble!

Cheers,
Felix

IntegerField instead of CharField

I understand the choice of CharField for ApproximateDateField but a PositiveIntegerField would be a better choice as that will allow sorting as well. E.g. can be used in order_by. What are your thoughts on this? (If you are agree I can create a pull request)

url patterns have changed since django 1.7

Trying to run on django 2.0 I got this error:
File "/home/mark/python-projects/django_date_extensions/example/urls.py", line 1, in
from django.conf.urls import patterns
ImportError: cannot import name 'patterns'

In urls.py, you have:

from django.conf.urls import patterns
from .views import view

urlpatterns = patterns(
    '',
    (r'^$', view),
)

In django 2.0 forward, I believe it should be

from django.urls import path
from .views import view

urlpatterns =[
    path('', view),
]

ApproximateDateField Filtering by None value never matches

Given an object with an ApproximateDateField (ADF), query for other objects with the same ADF. If the ADF field is None, other equivalent objects will not match.

e1 = MyEntity.objects.filter(pk=1)
assert e1.adf == None
e2 = MyEntity.objects.filter(pk=2)
assert e2.adf == None
assert MyEntity.objects.filter(adf=e1.adf).count() == 0

I would expect the query to return at least e2. I have to add special logic to filter instead on adf being equal to "" if adf is None.

I realize that in SQL that NULL <> NULL, but I tried doing this with other fields that support None and it worked.

My workaround:

q = q.filter(dob=self.dob) if self.dob != None else q.filter(dob='')

ApproximateDateField Django 2.2 Migration Generates TypeError

After upgrading to Django 2.2, I noticed I needed to generate some migrations. Note I was using version 2 of this library until just now, but upgrading to 3 didn't seem to help.

My model uses the field as follows:

dob = ApproximateDateField(default="", blank=True)

The migration created is:

    operations = [
        migrations.AlterField(
            model_name='snake',
            name='dob',
            field=django_date_extensions.fields.ApproximateDateField(blank=True, default=''),
        ),
    ]

When trying to migrate, I get the following error:

Traceback (most recent call last):
  File "./manage.py", line 27, in <module>
    raise e
  File "./manage.py", line 16, in <module>
    execute_from_command_line(sys.argv)
  File "/Users/john/.venv/mm/lib/python3.7/site-packages/django/core/management/__init__.py", line 381, in execute_from_command_line
    utility.execute()
  File "/Users/john/.venv/mm/lib/python3.7/site-packages/django/core/management/__init__.py", line 375, in execute
    self.fetch_command(subcommand).run_from_argv(self.argv)
  File "/Users/john/.venv/mm/lib/python3.7/site-packages/django/core/management/base.py", line 323, in run_from_argv
    self.execute(*args, **cmd_options)
  File "/Users/john/.venv/mm/lib/python3.7/site-packages/django/core/management/commands/sqlmigrate.py", line 30, in execute
    return super().execute(*args, **options)
  File "/Users/john/.venv/mm/lib/python3.7/site-packages/django/core/management/base.py", line 364, in execute
    output = self.handle(*args, **options)
  File "/Users/john/.venv/mm/lib/python3.7/site-packages/django/core/management/commands/sqlmigrate.py", line 64, in handle
    sql_statements = executor.collect_sql(plan)
  File "/Users/john/.venv/mm/lib/python3.7/site-packages/django/db/migrations/executor.py", line 225, in collect_sql
    state = migration.apply(state, schema_editor, collect_sql=True)
  File "/Users/john/.venv/mm/lib/python3.7/site-packages/django/db/migrations/migration.py", line 124, in apply
    operation.database_forwards(self.app_label, schema_editor, old_state, project_state)
  File "/Users/john/.venv/mm/lib/python3.7/site-packages/django/db/migrations/operations/fields.py", line 249, in database_forwards
    schema_editor.alter_field(from_model, from_field, to_field)
  File "/Users/john/.venv/mm/lib/python3.7/site-packages/django/db/backends/base/schema.py", line 535, in alter_field
    old_db_params, new_db_params, strict)
  File "/Users/john/.venv/mm/lib/python3.7/site-packages/django/db/backends/postgresql/schema.py", line 124, in _alter_field
    new_db_params, strict,
  File "/Users/john/.venv/mm/lib/python3.7/site-packages/django/db/backends/base/schema.py", line 648, in _alter_field
    old_default = self.effective_default(old_field)
  File "/Users/john/.venv/mm/lib/python3.7/site-packages/django/db/backends/base/schema.py", line 233, in effective_default
    return field.get_db_prep_save(self._effective_default(field), self.connection)
  File "/Users/john/.venv/mm/lib/python3.7/site-packages/django/db/models/fields/__init__.py", line 793, in get_db_prep_save
    return self.get_db_prep_value(value, connection=connection, prepared=False)
  File "/Users/john/.venv/mm/lib/python3.7/site-packages/django/db/models/fields/__init__.py", line 788, in get_db_prep_value
    value = self.get_prep_value(value)
  File "/Users/john/.venv/mm/lib/python3.7/site-packages/django_date_extensions/fields.py", line 146, in get_prep_value
    if not ansi_date_re.search(value):
TypeError: cannot use a string pattern on a bytes-like object

ImportError: cannot import name 'python_2_unicode_compatible'

Seems this might have to do with version support for django, and the use of the six package. For example: jazzband/django-auditlog#231

In my case:
python 3.6.9
django: 3.0.5

models.py:
from django_date_extensions.fields import ApproximateDateField

settings.py:
INSTALLED_APPS = [
...
'django_date_extensions'
....]

on makemigrations:
from django.utils.encoding import python_2_unicode_compatible
ImportError: cannot import name 'python_2_unicode_compatible'

Django 1.11: unexpected keyword argument 'empty_value'

Hi,

I've found django-date-extensions really useful with Django 1.10, but after switching to Django 1.11 I get the following error in fields.py:

File "...\lib\site-packages\django_date_extensions\fields.py", line 164, in init
super(ApproximateDateFormField, self).init(*args, **kwargs)
TypeError: init() got an unexpected keyword argument 'empty_value'

I use the ApproximateDateField in my model like this:

date = ApproximateDateField(null=True)

and set up the form in Django Admin like this, setting width and height for some form fields, but nothing special for theApproximateDateFormField:

def get_form(self, request, obj=None, **kwargs):
form = super(LetterAdmin, self).get_form(request, obj, **kwargs)
...
return form

I know that empty_value is a new attribute of CharField, added in Django 1.11, but I don't know what needs to be done about it. Are there plans to update django-date-extensions to support Django 1.11?

Thanks,
Claire

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.