Accessing move_in_date field within form causes KeyError

Model Terms has a field named move_in_date.
listings/models.py:

class Terms(models.Model):
    move_in_date = models.DateField(auto_now_add=True)
    deposit = models.BooleanField()
    for_students = models.BooleanField()
    for_workers = models.BooleanField()
    smoking_allowed = models.BooleanField()
    pets_allowed = models.BooleanField()

    class Meta:
        app_label = "listings"
        db_table = "terms"

    def format_move_in_date(self):
        return self.move_in_date.strftime("%d.%m.%Y")

I created a form for the model.
listings/forms.py:

class TermsForm(forms.ModelForm):
    class Meta:
        model = Terms
        fields = "__all__"
        error_messages = {"move_in_date": {"invalid": _("field.date").format(field=__("move_in_date"))}}
        widgets = {"move_in_date": forms.DateInput(attrs={"class": "form-control", "type": "date"})}

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        checkboxes = [field for field in self.fields if type(self.fields[field]) is forms.BooleanField]
        print(self.fields.keys())

        for field in checkboxes:
            self.fields[field].widget.attrs["class"] = "form-check-input"

        # 2 Input validation & sanitization
       self.fields["move_in_date"].validators.append(AfterOrEqualValidator(_("move_in_date.after_or_equal"))) # KeyError

I want to append a custom validator to the move_in_date. But accessing move_in_field within the form causes KeyError, despite all fields being enabled.

Traceback (most recent call last):
  File "D:\Documents\_Dokumenti\Projekti\_Master\Real Estate App\Django\secure\venv\Lib\site-packages\django\core\handlers\exception.py", line 55, in inner
    response = get_response(request)
               ^^^^^^^^^^^^^^^^^^^^^
  File "D:\Documents\_Dokumenti\Projekti\_Master\Real Estate App\Django\secure\venv\Lib\site-packages\django\core\handlers\base.py", line 198, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "D:\Documents\_Dokumenti\Projekti\_Master\Real Estate App\Django\secure\realestate\listings\views.py", line 64, in create
    return create_post(request, template) if request.method == "POST" else create_get(request, template)
                                                                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "D:\Documents\_Dokumenti\Projekti\_Master\Real Estate App\Django\secure\realestate\listings\views.py", line 34, in create_get
    terms_form = TermsForm()
                 ^^^^^^^^^^^
  File "D:\Documents\_Dokumenti\Projekti\_Master\Real Estate App\Django\secure\realestate\listings\forms.py", line 26, in __init__
    self.fields["move_in_date"].validators.append(AfterOrEqualValidator(_("move_in_date.after_or_equal")))
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^

Exception Type: KeyError at /oglasi/postavka
Exception Value: 'move_in_date'

listings/views.py:

def create_get(request: HttpRequest, template: str):
    terms_form = TermsForm()
    listing_form = ListingForm()

    context = form_context(terms_form, listing_form)
    return render(request, template, context)

I printed the field names to the console and move_in_date was missing.

dict_keys(['deposit', 'for_students', 'for_workers', 'smoking_allowed', 'pets_allowed'])

It’s because that field has auto_now_add=True. From the docs:

DateField.auto_now_add

Automatically set the field to now when the object is first created. Useful for creation of timestamps. Note that the current date is always used; it’s not just a default value that you can override. So even if you set a value for this field when creating the object, it will be ignored.

The ModelForm won’t add that field, as it’s effectively not an editable field.

How can I make it editable and still have default feed?

The docs I linked to tell you exactly how, in the paragraph beneath the one I quoted.

If you want to be able to modify this field, set the following instead of auto_now_add=True:

Reading the docs that people link you to will help you greatly in figuring these issues out :+1: