Model field with default value and choices is always reported as changed, even if unchanged

133 views
Skip to first unread message

Carsten Fuchs

unread,
Feb 25, 2015, 1:12:22 PM2/25/15
to django...@googlegroups.com
Hi all,

please consider this model definition:


def PrevMonth():
h = date.today()
return 12 if h.month == 1 else h.month-1

MONTHS_CHOICES = (
(1, "Januar"), (2, "Februar"), (3, "März"), (4, "April"),
(5, "Mai"), (6, "Juni"), (7, "Juli"), (8, "August"),
(9, "September"), (10, "Oktober"), (11, "November"), (12, "Dezember")
)

class TestModel(models.Model):
key = models.ForeignKey(ParentModel, db_column='key', to_field='key')
monat = models.SmallIntegerField(default=PrevMonth,
choices=MONTHS_CHOICES)


I use TestModel in the Django Admin "inline", i.e. as the related model
of ParentModel.

The problem is that whenever an existing ParentModel instance with
existing TestModel inlines is saved, the parent model's History view
claims that field "monat" of TestModel has been changed, even if it
hasn't. (If many instances of TestModel refer to the same parent model
instance, the claim is made for each TestModel instance.)

The problem disappears if in the definition of field `monat`, either
parameter `default` or `choices` is omitted. It also disappears if I
change the definition to use a constant for the default value, e.g.
`default=6`.

Does someone know what may be causing this, or how (else) it can be avoided?

Best regards,
Carsten

Carsten Fuchs

unread,
Feb 26, 2015, 1:08:24 PM2/26/15
to django...@googlegroups.com
Hi,

Am 25.02.2015 um 19:11 schrieb Carsten Fuchs:
> the parent model's History view claims that field "monat" of TestModel has been changed,

I got at least a little bit further: This is easily reproducible in a
minimal project/app test case with SQLite exactly as described in
Django's intro tutorial 01. This is the entire contents of my test app's
`models.py` file:


# -*- coding: utf-8 -*-
from django.db import models

def VormonatsMonat():
return 1

MONTHS_CHOICES = (
(1, "Jan"),
(2, "Feb"),
)

class Choice(models.Model):
choice_text = models.CharField(max_length=200)
votes = models.IntegerField(default=0)
monat = models.IntegerField(default=VormonatsMonat,
choices=MONTHS_CHOICES)


Then, at the `./manage.py shell` prompt (creating a Choice instance is
omitted here):

>>> from django.forms import ModelForm
>>> from TestApp.models import Choice
>>> class ChoiceForm(ModelForm):
... class Meta:
... model = Choice
... fields = ["choice_text", "votes", "monat"]
...
>>> ch = Choice.objects.get(pk=1)
>>> chv = Choice.objects.values().get(pk=1)
>>> ch
<Choice: Choice object>
>>> chv
{'monat': 1, 'choice_text': u'just a test', 'votes': 0, u'id': 1}
>>> ChoiceForm(chv, initial=chv, instance=ch).has_changed()
True


The expected output is `False`, which is (in a new shell session) in
fact obtained whenever the definition of field `monat` is slightly
changed, e.g. to a constant default value rather than a callable, or
with no choices.

Any thoughts please?

Best regards,
Carsten

Carsten Fuchs

unread,
Feb 27, 2015, 4:17:45 PM2/27/15
to django...@googlegroups.com
Am 26.02.2015 um 19:06 schrieb Carsten Fuchs:
> The expected output is `False`,[...]

Just for future reference, this is continued here:
https://code.djangoproject.com/ticket/24428

Best regards,
Carsten

Reply all
Reply to author
Forward
0 new messages