Django form fields order

35 views
Skip to first unread message

אורי

unread,
Apr 10, 2020, 3:30:04 AM4/10/20
to django...@googlegroups.com
Hi,

We are using Django 2.2 and I want to upgrade to Django 3.0. We have a mixin (written in 2017) that add fields to forms:

class LocalizedFirstLastNameMixin(object):
def __init__(self, *args, **kwargs):
self.language_code = kwargs.pop('language_code', 'en')
super().__init__(*args, **kwargs)
for loc_field in reversed(self.get_localized_fields()):
self.fields[loc_field] = User._meta.get_field(loc_field).formfield()
self.fields[loc_field].required = True
self.fields.move_to_end(loc_field, last=False)
self.initial[loc_field] = getattr(self.instance, loc_field, '')

It works with Django versions up to 2.2. But when I upgrade to 3.0, I get this error message:

AttributeError: 'dict' object has no attribute 'move_to_end'

This function's info:
'''Move an existing element to the end (or beginning if last==False).
And it belongs to OrderedDict.

So I guess we want these fields to be in the beginning of the form fields.

Is there a change in the implementation of the fields in forms and how do I specify the order of fields? And if I change it, will it work in previous versions such as Django 2.2?

Thanks,
Uri.
אורי

אורי

unread,
Apr 10, 2020, 3:46:12 AM4/10/20
to django...@googlegroups.com
Hi,

I want to add that I checked the Django 3.0 release notes [ https://docs.djangoproject.com/en/3.0/releases/3.0/ ] and also releases from 3.0.1 to 3.0.5 and I didn't find any documentation of this issue.
 

Mike Dewhirst

unread,
Apr 10, 2020, 3:53:22 AM4/10/20
to django...@googlegroups.com
On 10/04/2020 5:28 pm, אורי wrote:
> Hi,
>
> We are using Django 2.2 and I want to upgrade to Django 3.0. We have a
> mixin (written in 2017) that add fields to forms:
>
> class LocalizedFirstLastNameMixin(object):
> def __init__(self, *args, **kwargs):
> self.language_code = kwargs.pop('language_code','en')
> super().__init__(*args, **kwargs)
> for loc_fieldin reversed(self.get_localized_fields()):
> self.fields[loc_field] = User._meta.get_field(loc_field).formfield()
> self.fields[loc_field].required =True self.fields.move_to_end(loc_field,last=False)
> self.initial[loc_field] =getattr(self.instance, loc_field,'')
>
> It works with Django versions up to 2.2. But when I upgrade to 3.0, I
> get this error message:
>
> AttributeError: 'dict' object has no attribute 'move_to_end'
>
> This function's info:
> '''Move an existing element to the end (or beginning if last==False).
> And it belongs to OrderedDict.
>
> So I guess we want these fields to be in the beginning of the form fields.
>
> Is there a change in the implementation of the fields in forms and how
> do I specify the order of fields? And if I change it, will it work in
> previous versions such as Django 2.2?

I don't know but I recently decided to follow a different path. I think
this has been advocated by Russell Keith-Magee who has (I think) built a
custom user template ... well what I mean is you may not need to go
swapping those fields around and you may even make your project more
attractive to everyone.

Instead of first_name, last_name you adjust your thinking to ...

short_name, full_name

You can use the same fields and only change the way you use them.

Everyone on the planet has a full name and they are the only people who
really know how it should be written. Everyone on the planet may or may
not have a short name they prefer others to use. If they do, they also
know exactly how that should be written.

What Russell was saying is that it is only western nations who have the
first name last name hangup. Software devs have been trying to squeeze
non-western names into first_name, last_name ever since computers were
used to store human data.

I started last century doing the same thing with a switch to swap them.
What a waste of time! There are times you need a short name and every
other time you need the full name exactly as it is written.

I found it remarkably easy to transition.

It would simplify your software and be compatible between 2.2 and 3.x

That'll be 2c

Mike

>
> Thanks,
> Uri.
> אורי
> u...@speedy.net <mailto:u...@speedy.net>
> --
> You received this message because you are subscribed to the Google
> Groups "Django users" group.
> To unsubscribe from this group and stop receiving emails from it, send
> an email to django-users...@googlegroups.com
> <mailto:django-users...@googlegroups.com>.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/django-users/CABD5YeEbHc5ewqJKEFAS5XV1JfD%3DEqf8%3D_ScgjhTC5VY2NsDpw%40mail.gmail.com
> <https://groups.google.com/d/msgid/django-users/CABD5YeEbHc5ewqJKEFAS5XV1JfD%3DEqf8%3D_ScgjhTC5VY2NsDpw%40mail.gmail.com?utm_medium=email&utm_source=footer>.

אורי

unread,
Apr 10, 2020, 4:26:32 AM4/10/20
to django...@googlegroups.com
Hi Mike,

Thanks for your suggestion. But right now, I'm looking for a solution without changing the database and the models. I agree that first name / last name is not the best way to name people but it's already this way in my website (Speedy Net). People are not required to use a real / certificated name but only that it's not empty. I agree that maybe short name & full name are better, however both Facebook and Google still require both first name and last name when signing up. And by the way Twitter requires just "name", maybe this is better than short name & full name but regarding the form, it doesn't matter what are the names of the fields, what matters is that they depend on the language, so one can have different (spellings of) names in different languages. For example I can write Uri in English, and אורי in Hebrew, which will be both saved to the database in different fields. So even if I change to one field (name), I still need the code above without changes.

By the way, I might just leave the last name as optional and the first name would be the name.


To unsubscribe from this group and stop receiving emails from it, send an email to django-users...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/django-users/3d5e03ad-4240-f216-1655-ca5a16d4f748%40dewhirst.com.au.

Jorge Gimeno

unread,
Apr 10, 2020, 4:14:37 PM4/10/20
to django...@googlegroups.com
--
You received this message because you are subscribed to the Google Groups "Django users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to django-users...@googlegroups.com.

By chance did you change Python versions as well?

-Jorge

Jason

unread,
Apr 10, 2020, 7:42:29 PM4/10/20
to Django users
python dicts are ordered in terms of insertion order as an implementation detail in cpython 3.6, and was made part of the spec in 3.7.  You might be getting bit by this.

Mike Dewhirst

unread,
Apr 10, 2020, 10:05:46 PM4/10/20
to django...@googlegroups.com
On 10/04/2020 6:24 pm, אורי wrote:
> Hi Mike,
>
> Thanks for your suggestion. But right now, I'm looking for a solution
> without changing the database and the models.

This is the way I do it without changing the database. The only model
changes are verbose name and overriding two Django model methods.

class User(AbstractUser):

    first_name = models.CharField(_('short name'), max_length=30,
blank=True)
    last_name = models.CharField(_('full name'), max_length=150,
blank=True)

    ...

    def get_full_name(self):
        full_name = "{0}".format(self.last_name or self.first_name or
self.username)
        bits = full_name.split()
        if len(bits) > 1:
            # assume full name
            return full_name
        # might be old data
        full_name = "{0} {1}".format(self.first_name,
self.last_name).strip()
        return full_name if fullname else self.username

    def get_short_name(self):
        if "@" in self.username:
            return self.username
        return self.first_name or self.last_name or self.username


> I agree that first name / last name is not the best way to name
> people but it's already this way in my website (Speedy Net). People
> are not required to use a real / certificated name but only that it's
> not empty. I agree that maybe short name & full name are better,
> however both Facebook and Google still require both first name and
> last name when signing up. And by the way Twitter requires just
> "name", maybe this is better than short name & full name but regarding
> the form, it doesn't matter what are the names of the fields, what
> matters is that they depend on the language, so one can have different
> (spellings of) names in different languages. For example I can write
> Uri in English, and אורי in Hebrew, which will be both saved to the
> database in different fields. So even if I change to one field (name),
> I still need the code above without changes.

Ok, I get it. I'm guessing alternative names in different languages have
to be kept in extra records in a separate table. Which must mean your
get_short_name() and get_full_name() are more complex and hence require
the middleware approach.

All the best

Mike

>
> By the way, I might just leave the last name as optional and the first
> name would be the name.
> אורי
> u...@speedy.net <mailto:u...@speedy.net>
> > u...@speedy.net <mailto:u...@speedy.net> <mailto:u...@speedy.net
> <mailto:u...@speedy.net>>
> > --
> > You received this message because you are subscribed to the Google
> > Groups "Django users" group.
> > To unsubscribe from this group and stop receiving emails from
> it, send
> > an email to django-users...@googlegroups.com
> <mailto:django-users%2Bunsu...@googlegroups.com>
> > <mailto:django-users...@googlegroups.com
> <mailto:django-users%2Bunsu...@googlegroups.com>>.
> > To view this discussion on the web visit
> >
> https://groups.google.com/d/msgid/django-users/CABD5YeEbHc5ewqJKEFAS5XV1JfD%3DEqf8%3D_ScgjhTC5VY2NsDpw%40mail.gmail.com
>
> >
> <https://groups.google.com/d/msgid/django-users/CABD5YeEbHc5ewqJKEFAS5XV1JfD%3DEqf8%3D_ScgjhTC5VY2NsDpw%40mail.gmail.com?utm_medium=email&utm_source=footer>.
>
> --
> You received this message because you are subscribed to the Google
> Groups "Django users" group.
> To unsubscribe from this group and stop receiving emails from it,
> send an email to django-users...@googlegroups.com
> <mailto:django-users%2Bunsu...@googlegroups.com>.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/django-users/3d5e03ad-4240-f216-1655-ca5a16d4f748%40dewhirst.com.au.
>
> --
> You received this message because you are subscribed to the Google
> Groups "Django users" group.
> To unsubscribe from this group and stop receiving emails from it, send
> an email to django-users...@googlegroups.com
> <mailto:django-users...@googlegroups.com>.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/django-users/CABD5YeGNZa57D2A9EYP_5fviNC1spBWbVA_YsD%2B_8r5fmJZSkA%40mail.gmail.com
> <https://groups.google.com/d/msgid/django-users/CABD5YeGNZa57D2A9EYP_5fviNC1spBWbVA_YsD%2B_8r5fmJZSkA%40mail.gmail.com?utm_medium=email&utm_source=footer>.

אורי

unread,
Apr 10, 2020, 11:37:29 PM4/10/20
to django...@googlegroups.com
On Fri, Apr 10, 2020 at 11:13 PM Jorge Gimeno <jlgim...@gmail.com> wrote:

By chance did you change Python versions as well?


No, it's the same Python version (3.6). Anyway, I asked also on Stack Overflow and found a solution:

Thanks! 
Reply all
Reply to author
Forward
0 new messages