-1

I'm using Django 2.2 forms and I'm trying to understand why the below two snippets have different behaviors. Why does passing a @staticmethod to initial in the form field (snippet A) not have the same result as passing an unbound function (snippet B)?

Snippet A:

class BankUpdateForm(forms.Form):
    @staticmethod
    def yesterday():
        return date.today() - timedelta(days=1)    

    from_date =  forms.DateField(initial=yesterday)
    to_date =  forms.DateField(initial=date.today)

Snippet B:

def yesterday():
        return date.today() - timedelta(days=1)
class BankUpdateForm(forms.Form):
    from_date =  forms.DateField(initial=yesterday)
    to_date =  forms.DateField(initial=date.today)

Snippet B will work as intended and show the correct initial field value. Snippet A will only print the function's str.

enter image description here

Jad S
  • 2,705
  • 6
  • 29
  • 49

2 Answers2

0

From the source code,

def get_initial_for_field(self, field, field_name):
    """
    Return initial data for field on form. Use initial data from the form
    or the field, in that order. Evaluate callable values.
    """
    value = self.initial.get(field_name, field.initial)
    if callable(value):
        value = value()
    return value

Which indicates, the yesterday is not a callable method, but BankUpdateForm.yesterday is.

To execute staticmethods, you should call it with their class as, BankUpdateForm.yesterday, which is not possible while defining the form fields.

So, You don't have to use @staticmethod decorator here,

# Method-1
class BankUpdateForm(forms.Form):

    def yesterday():
        return date.today() - timedelta(days=1)

    from_date = forms.DateField(initial=yesterday)
    to_date = forms.DateField(initial=date.today)

# Method-2 (You already have this)
def yesterday():
    return date.today() - timedelta(days=1)


class BankUpdateForm(forms.Form):
    from_date = forms.DateField(initial=yesterday)
    to_date = forms.DateField(initial=date.today)
JPG
  • 82,442
  • 19
  • 127
  • 206
  • staticmethods can be called using the object directly intead of class: https://stackoverflow.com/questions/136097/difference-between-staticmethod-and-classmethod – Tâmer Cuba Jul 05 '20 at 03:37
  • Could you reference the exact answer you want to refer here? Unfortunately, I didn't see any example that calls a static method without using it's class – JPG Jul 05 '20 at 04:01
  • The first answer shows it. Btw my point is: objects can call staticmethods too. – Tâmer Cuba Jul 06 '20 at 02:02
  • Yes, ***objects can call `staticmethod`s too***, but not in this case since we have no objects here. @TâmerPinheiro – JPG Jul 06 '20 at 03:22
0

because yestday is a staticmethod, so callable(yestday) return False, then just return the function when getting the intial value for field. You can just drop @staticmethod decorator,it works well; or pass BankUpdateForm.yestday to initial, it does too. Note that staticmethod should be called by a class or instance, even if it's called in its class scope.

Blackdoor
  • 922
  • 1
  • 6
  • 12