Old description:
> I've only encountered Django once before (installing mailman3), but this
> time I was trying to install NetBox and I noticed this sentence in their
> documentation...
>
> "Specifying an email address for the user is not required" (search for
> that line in the URL below for better context)
>
> [https://docs.netbox.dev/en/stable/installation/3-netbox/]
>
> According to this line...
> [https://github.com/django/django/blob/main/django/contrib/auth/models.py#L378]
>
> The 'email' field is marked as required, but is also marked in a way to
> allow it to be empty.
>
> This is the section of the code that deals with validating required
> fields when createsuperuser is called **interactively**...
> [https://github.com/django/django/blob/main/django/contrib/auth/management/commands/createsuperuser.py#L143]
>
> This is the section of the code that deals with validating required
> fields when createsuperuser is called **non-interactively**...
> [https://github.com/django/django/blob/main/django/contrib/auth/management/commands/createsuperuser.py#L219]
>
> Although required fields are enforced, the **non-interactive** code
> doesn't allow for those to be blank, where blank required fields are
> permitted. I've tried to set a field like 'email' to blank **non-
> interactively** but nothing works, for example...
>
> a) just don't set the email field either through an argument or an
> environment variable... it'll complain it is needed
> b) set the email field via a variable as just 'DJANGO_SUPERUSER_EMAIL='
> (i.e. setting the variable to null)... it still complains it is needed
> c) set the email field via an argument of --email '' (i.e. double quotes)
> or --email "" (i.e. double single quotes) or even --email \ (i.e.
> passing a single space)... it still complains it is needed
>
> Hope this makes sense :)
New description:
I've only encountered Django once before (installing mailman3), but this
time I was trying to install NetBox and I noticed this sentence in their
documentation...
"Specifying an email address for the user is not required" (search for
that line in the URL below for better context)
[https://docs.netbox.dev/en/stable/installation/3-netbox/]
According to these lines...
[https://github.com/django/django/blob/main/django/contrib/auth/models.py#L378]
and
[https://github.com/django/django/blob/main/django/contrib/auth/models.py#L358]
The 'email' field is marked as required, but is also marked in a way to
allow it to be empty.
This section of the code validates required fields when createsuperuser is
called **interactively**...
[https://github.com/django/django/blob/main/django/contrib/auth/management/commands/createsuperuser.py#L143]
This section of the code validates required fields when createsuperuser is
called **non-interactively**...
[https://github.com/django/django/blob/main/django/contrib/auth/management/commands/createsuperuser.py#L219]
Although required fields are enforced, the **non-interactive** code
doesn't allow for those to be blank, where blank required fields are
permitted. I've tried to set a field like 'email' to blank **non-
interactively** but nothing works, for example...
a) just don't set the email field either through an argument or an
environment variable... it'll complain it is needed
b) set the email field via a variable as just 'DJANGO_SUPERUSER_EMAIL='
(i.e. setting the variable to null)... it still complains it is needed
c) set the email field via an argument of --email '' (i.e. double quotes)
or --email "" (i.e. double single quotes) or even --email \ (i.e. passing
a single space)... it still complains it is needed
Hope this makes sense :)
--
--
Ticket URL: <https://code.djangoproject.com/ticket/34542#comment:6>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.
* stage: Unreviewed => Accepted
Comment:
Thanks Lantizia, you have a valid point, we could make the
noninteractively process allow for the empty string for email, to match
the behavior of the interactive and web experience, but only when either
the `--email` or env var should be passed as such though.
Would you like to prepare a patch?
--
Ticket URL: <https://code.djangoproject.com/ticket/34542#comment:7>
* owner: nobody => ATausif
* status: new => assigned
--
Ticket URL: <https://code.djangoproject.com/ticket/34542#comment:8>
* owner: ATausif => (none)
* status: assigned => new
--
Ticket URL: <https://code.djangoproject.com/ticket/34542#comment:9>
* owner: nobody => Anvansh Singh
* status: new => assigned
Comment:
I will be preparing a patch for it. Will send it out by next wednesday.
--
Ticket URL: <https://code.djangoproject.com/ticket/34542#comment:8>
Comment (by Mohit Singh Sinsniwal):
Replying to [comment:7 Natalia Bidart]:
> Thanks Lantizia, you have a valid point, we could make the
noninteractively process allow for the empty string for email, to match
the behavior of the interactive and web experience, but only when either
the `--email` or env var should be passed as such though.
>
> Would you like to prepare a patch?
I want to work on this. However, I would like to understand what we want
to solve. If we give an email and username with --noinput, it does not
require the password.
{{{
python3.11 manage.py createsuperuser --email "a...@b.com" --user mohitd
--noinput
}}}
And if we dont want to write the email, it will require the password.
{{{
python3.11 manage.py createsuperuser --email "" --user mohite
}}}
Do we want to create --noinput with no email? Because that means creating
a superuser without giving an email and password
--
Ticket URL: <https://code.djangoproject.com/ticket/34542#comment:9>
Comment (by Natalia Bidart):
Replying to [comment:9 Mohit Singh Sinsniwal]:
> Replying to [comment:7 Natalia Bidart]:
> > Thanks Lantizia, you have a valid point, we could make the
noninteractively process allow for the empty string for email, to match
the behavior of the interactive and web experience, but only when either
the `--email` or env var should be passed as such though.
> >
> > Would you like to prepare a patch?
> I want to work on this. However, I would like to understand what we want
to solve. If we give an email and username with --noinput, it does not
require the password.
> {{{
> python3.11 manage.py createsuperuser --email "a...@b.com" --user mohitd
--noinput
> }}}
>
> And if we dont want to write the email, it will require the password.
> {{{
> python3.11 manage.py createsuperuser --email "" --user mohite
> }}}
Hi! I'm not entirely sure what you are asking, since your original report
was about using `--noinput` without passing an email explicitely. In the
`--noinput` case, password is not asked via the prompt (but it's used from
the env var if given), so we want something similar. So if the command is
called with something like this:
{{{
python -Wall manage.py createsuperuser --username=adminusername --email
--noinput
}}}
or this:
{{{
DJANGO_SUPERUSER_EMAIL= python -Wall manage.py createsuperuser
--username=adminusername --noinput
}}}
the superuser should be created with no email. Password can be provided
via the `DJANGO_SUPERUSER_PASSWORD` env var.
> Do we want to create --noinput with no email? Because that means
creating a superuser without giving an email and password
We understood this was your ask in the bug report. If it wasn't, what's
your expected outcome then?
Thanks!
--
Ticket URL: <https://code.djangoproject.com/ticket/34542#comment:10>
Comment (by SyedMa3):
Replying to [ticket:34542 Lantizia]:
I just tried making a superuser non-interactively using the command
`python manage.py createsuperuser --email "" --user admin`
and it works without any error.
Is this bug still valid? @Lantizia
--
Ticket URL: <https://code.djangoproject.com/ticket/34542#comment:11>
Comment (by Natalia Bidart):
Syed, can you please your whole invocation and shell result? For me, your
command prompts for password:
{{{
$ python manage.py createsuperuser --email "" --user admin
Password:
Operation cancelled.
}}}
And when passing `--nopinput`, I get an error:
{{{
$ python manage.py createsuperuser --email "" --user admin --noinput
CommandError: You must use --email with --noinput.
}}}
--
Ticket URL: <https://code.djangoproject.com/ticket/34542#comment:12>
Comment (by Mateusz Więckowski):
Hi! I'm not entirely sure that I understood the problem, but if so, I do
believe I have created a solution.
In the 'non-interactive' part of the code where the error is thrown (e.g.,
CommandError: You must use --email with --noinput), I added a block of
code that checks if the field is allowed to be blank. If that's the case,
I simply do not raise the error.
This is how it works for me now:
{{{
py manage.py createsuperuser --username username --noinput
Superuser created successfully.
}}}
Let me know if that's what was the issue with this one.
--
Ticket URL: <https://code.djangoproject.com/ticket/34542#comment:13>
Comment (by Natalia Bidart):
Hello Mateusz, the goal for the fix is to allow the email value to be
blank, not to allow it to be missing. So basically an invocation with
`--email ""` should succeed but not passing `--email` at all should fail
for `noinput` or should prompt for `email` if interactive.
Does that make sense?
--
Ticket URL: <https://code.djangoproject.com/ticket/34542#comment:14>
Comment (by Mateusz Więckowski):
Okay, got It. This is how it works for me now:
{{{
py manage.py createsuperuser --username testing --noinput
CommandError: You must use --email with --noinput.
py manage.py createsuperuser --email "" --username testing --noinput
Superuser created successfully.
}}}
I did not change anything for the "interactive" part of the process - as
far as I've understood from the comments it works as intended.
--
Ticket URL: <https://code.djangoproject.com/ticket/34542#comment:15>
Comment (by Natalia Bidart):
Replying to [comment:15 Mateusz Więckowski]:
> Okay, got It. This is how it works for me now:
>
>
> {{{
> py manage.py createsuperuser --username testing --noinput
> CommandError: You must use --email with --noinput.
>
> py manage.py createsuperuser --email "" --username testing --noinput
> Superuser created successfully.
> }}}
>
> I did not change anything for the "interactive" part of the process - as
far as I've understood from the comments it works as intended.
Thanks for sharing this. What shell are you using? I'm using bash on an
ubuntu system with Python 3.11, and I get this:
{{{
$ python -Wall manage.py createsuperuser --email "" --username testing
--noinput
CommandError: You must use --email with --noinput.
}}}
--
Ticket URL: <https://code.djangoproject.com/ticket/34542#comment:16>
Comment (by Mateusz Więckowski):
I'm using cmd. I did some changes to "non-interactive" part in Django's
createsuperuser.py
It's rather quick, so you could do it yourself and check:
Move this line:
https://github.com/django/django/blob/main/django/contrib/auth/management/commands/createsuperuser.py#L226
above the if statement at the line 222
In the if itself add the following:
{{{
if field.blank and options[field_name] is not None:
continue
}}}
--
Ticket URL: <https://code.djangoproject.com/ticket/34542#comment:17>
Comment (by Natalia Bidart):
Replying to [comment:17 Mateusz Więckowski]:
> I'm using cmd. I did some changes to "non-interactive" part in Django's
createsuperuser.py
>
> It's rather quick, so you could do it yourself and check:
> Move this line:
>
https://github.com/django/django/blob/main/django/contrib/auth/management/commands/createsuperuser.py#L226
> above the if statement at the line 222
> In the if itself add the following:
> {{{
> if field.blank and options[field_name] is not None:
> continue
> }}}
>
Would you like to prepare a patch/PR? Please note that the solution should
also work when passing the env var `DJANGO_SUPERUSER_EMAIL` (on both
interactive and `--noinput` mode).
--
Ticket URL: <https://code.djangoproject.com/ticket/34542#comment:18>
Comment (by Mateusz Więckowski):
When passing DJANGO_SUPERUSER_EMAIL:
{{{
py manage.py createsuperuser --username username
}}}
Prompts for email, allows it to be blank, doesn't get value from
DJANGO_SUPERUSER_EMAIL.
{{{
py manage.py createsuperuser --email "" --username username
}}}
Doesn't prompt for email, doesn't get value from DJANGO_SUPERUSER_EMAIL,
sets email blank.
{{{
py manage.py createsuperuser --email "" --username username --noinput
py manage.py createsuperuser --username username --noinput
}}}
Doesn't prompt, gets value from DJANGO_SUPERUSER_EMAIL.
I believe it works how it's supposed to. Is that correct?
--
Ticket URL: <https://code.djangoproject.com/ticket/34542#comment:19>
Comment (by Natalia Bidart):
Hello Mateusz,
Did you run the examples above with or without your changes? Using Django
main, this is what I get:
{{{
$ DJANGO_SUPERUSER_EMAIL="" python -Wall manage.py createsuperuser
--username testing --noinput
CommandError: You must use --email with --noinput.
}}}
If you are confident that your proposal is correct and works for every
case, then please create a PR and I'll happily review. Thanks!
--
Ticket URL: <https://code.djangoproject.com/ticket/34542#comment:20>
Comment (by Lufafa Joshua):
Replying to [# Mateusz Więckowski]:
>I'm using cmd. I did some changes to "non-interactive" part in Django's
createsuperuser.py
>It's rather quick, so you could do it yourself and check:
>Move this line:
>https://github.com/django/django/blob/main/django/contrib/auth/management/commands/createsuperuser.py#L226
>above the if statement at the line 222
>In the if itself add the following:
>{{{
>if field.blank and options[field_name] is not None:
>continue
>}}}
Hey, Considering your approach, instead of using:
{{{
if field.blank and options[field_name] is not None:
continue
}}}
I have used
{{{
if field.blank:
continue
}}}
and it seems to bypass the exception if the field is allowed to be blank
while using environment variable or {{{--noinput}}}
--
Ticket URL: <https://code.djangoproject.com/ticket/34542#comment:21>
Comment (by Mateusz Więckowski):
Replying to [comment:21 Lufafa Joshua]:
>
> Replying to [# Mateusz Więckowski]:
> >I'm using cmd. I did some changes to "non-interactive" part in Django's
createsuperuser.py
> >It's rather quick, so you could do it yourself and check:
> >Move this line:
>
>https://github.com/django/django/blob/main/django/contrib/auth/management/commands/createsuperuser.py#L226
> >above the if statement at the line 222
> >In the if itself add the following:
> >{{{
> >if field.blank and options[field_name] is not None:
> >continue
> >}}}
> Hey, Considering your approach, instead of using:
>
> {{{
> if field.blank and options[field_name] is not None:
> continue
> }}}
> I have used
> {{{
> if field.blank:
> continue
> }}}
> and it seems to bypass the exception if the field is allowed to be blank
while using environment variable or {{{--noinput}}}
>
>
>
>
>
>
Hey, that was my initial approach, but it creates unwanted behavior that
is described in comments: #comment:13 and #comment:14.
I've also found that this:
{{{
if field.blank and options[field_name] is not None:
continue
}}}
Doesn't work for all cases when setting DJANGO_SUPERUSER_EMAIL.
My current approach looks like this and works for all cases I could've
found.
{{{
if not value:
if (field.blank and
(options[field_name] is not None or
os.environ.get(env_var) is not None)):
continue
}}}
--
Ticket URL: <https://code.djangoproject.com/ticket/34542#comment:22>
Comment (by Mateusz Więckowski):
Replying to [comment:20 Natalia Bidart]:
> Hello Mateusz,
>
> Did you run the examples above with or without your changes? Using
Django main, this is what I get:
>
> {{{
> $ DJANGO_SUPERUSER_EMAIL="" python -Wall manage.py createsuperuser
--username testing --noinput
> CommandError: You must use --email with --noinput.
> }}}
>
> If you are confident that your proposal is correct and works for every
case, then please create a PR and I'll happily review. Thanks!
I ran the examples with my changes. I found one case with environmental
variables that wasn't working, but managed to fix it.
At the moment I am confident that my current solution works, but before
doing the PR I have just one question - should I write tests as well? In
the ticket details, it says 'Needs tests: no', but in the guide about
creating a PR, it's mentioned that tests are always needed, except for
documentation changes.
--
Ticket URL: <https://code.djangoproject.com/ticket/34542#comment:23>
Comment (by Sarah Boyce):
Replying to [comment:23 Mateusz Więckowski]:
>
> At the moment I am confident that my current solution works, but before
doing the PR I have just one question - should I write tests as well? In
the ticket details, it says 'Needs tests: no', but in the guide about
creating a PR, it's mentioned that tests are always needed, except for
documentation changes.
Yes you should write tests. The 'Needs tests' area of the ticket is marked
as 'Yes' when there was a patch that got reviewed and it was missing
tests, then this is part of the feedback as to why the patch has not been
accepted. 👍
--
Ticket URL: <https://code.djangoproject.com/ticket/34542#comment:24>
* owner: Anvansh Singh => Mateusz Więckowski
* has_patch: 0 => 1
--
Ticket URL: <https://code.djangoproject.com/ticket/34542#comment:25>
* needs_better_patch: 0 => 1
--
Ticket URL: <https://code.djangoproject.com/ticket/34542#comment:26>
* needs_better_patch: 1 => 0
* stage: Accepted => Ready for checkin
--
Ticket URL: <https://code.djangoproject.com/ticket/34542#comment:27>
* status: assigned => closed
* resolution: => fixed
Comment:
In [changeset:"5aa4c0b67549f1d7ab649f53ac782d8de3e6a87c" 5aa4c0b]:
{{{
#!CommitTicketReference repository=""
revision="5aa4c0b67549f1d7ab649f53ac782d8de3e6a87c"
Fixed #34542 -- Made createsuperuser handle required blank fields in non-
interactive mode.
}}}
--
Ticket URL: <https://code.djangoproject.com/ticket/34542#comment:28>