Tự động tạo người dùng quản trị khi chạy Django's ./manage.py syncdb


82

Dự án của tôi đang trong giai đoạn đầu phát triển. Tôi thường xuyên xóa cơ sở dữ liệu và chạy manage.py syncdbđể thiết lập ứng dụng của mình từ đầu.

Thật không may, điều này luôn bật lên:

You just installed Django's auth system, which means you don't have any superusers defined.
Would you like to create one now? (yes/no): 

Sau đó, bạn đã cung cấp tên người dùng, địa chỉ email hợp lệ và mật khẩu. Điều này là tẻ nhạt. Tôi cảm thấy mệt mỏi khi gõ test\nx@x.com\ntest\ntest\n.

Làm cách nào để có thể tự động bỏ qua bước này và tạo người dùng theo chương trình khi chạy manage.py syncdb?


syncdbđã không được dùng nữa để ủng hộ việc di chuyển dữ liệu
Sdra

Câu trả lời:


80

Tôi biết câu hỏi đã được trả lời nhưng ...

Một cách tiếp cận đơn giản hơn nhiều là kết xuất dữ liệu mô-đun auth vào một tệp json khi superuser đã được tạo:

 ./manage.py dumpdata --indent=2 auth > initial_data.json

Bạn cũng có thể kết xuất dữ liệu phiên:

./manage.py dumpdata --indent=2 sessions

Sau đó, bạn có thể nối thông tin phiên vào kết xuất mô-đun auth (và có thể tăng expire_date để nó không hết hạn ... bao giờ hết ;-).

Từ đó, bạn có thể sử dụng

/manage.py syncdb --noinput

để tải superuser và phiên của anh ấy khi tạo db mà không có lời nhắc tương tác hỏi bạn về superuser.


1
Đây thực sự phải là câu trả lời được chấp nhận. IMO đơn giản nhất. Liên kết bị hỏng. :(
bnjmn 31/07/13

4
Tôi nên đặt ở đâu initial_data.jsonđể syncdbtìm thấy nó? Tài liệu cho biết: "Trong thư mục đồ đạc của mọi ứng dụng đã cài đặt" . Đó là vd ./eggs/Django-1.6.5-py2.7.egg/django/contrib/auth/fixtures?
user272735

2
Tính năng này không được dùng nữa kể từ Django 1.7: docs.djangoproject.com/en/1.7/howto/initial-data/… Giờ đây, bạn có thể sử dụng Di chuyển dữ liệu.
Germain Chazot

49

Thay vì xóa toàn bộ cơ sở dữ liệu của bạn, chỉ cần xóa các bảng trong ứng dụng của bạn trước khi chạy syncdb

Điều này sẽ thực hiện nó cho bạn trong một dòng (mỗi ứng dụng):

python manage.py sqlclear appname | python manage.py dbshell

Lệnh đầu tiên sẽ xem xét ứng dụng của bạn và tạo SQL cần thiết để loại bỏ các bảng. Đầu ra này sau đó được chuyển đến dbshell để thực thi nó.

Sau khi hoàn tất, hãy chạy syncdb của bạn để tạo lại các bảng:

python manage.py syncdb

2
Tôi thích câu trả lời này. Cám ơn vì sự gợi ý!
ropable

tôi cũng vậy cảm ơn! giải pháp sạch, đã sử dụng nó để có một bãi chứa sạch mà tôi đồng bộ hóa bất cứ khi nào tôi cần.
Andrei-Niculae Petre

28

Điều quan trọng là sử dụng --noinputtại thời điểm syncdb và sau đó sử dụng điều này one linerđể tạo siêu người dùng

echo "from django.contrib.auth.models import User; User.objects.create_superuser('myadmin', 'myemail@example.com', 'hunter2')" | python manage.py shell

Tín dụng: http://source.mihelac.org/2009/10/23/django-avoiding-typing-password-for-superuser/


5
Cảm ơn! Điều này rõ ràng hơn những cái khác, mạnh mẽ hơn và có thể mở rộng và tuyệt vời để sử dụng trong lần đầu tiên bạn chạy mã của mình, cũng như trong các kịch bản thử nghiệm và các tình huống triển khai nhất định, và tất nhiên đối với kịch bản phát triển dẫn đến câu hỏi.
nealmcb

16

Nếu bạn muốn khả năng - như tôi làm - thực sự bắt đầu với một cơ sở dữ liệu mới mà không bị hỏi câu hỏi siêu người dùng đó, thì bạn có thể bỏ đăng ký bộ xử lý tín hiệu hỏi câu hỏi đó. Kiểm tra phần cuối của tệp:

django/contrib/auth/management/__init__.py

để xem việc đăng ký chức năng superuser được thực hiện như thế nào. Tôi thấy rằng tôi có thể đảo ngược đăng ký này và không bao giờ bị hỏi câu hỏi trong "syncdb", nếu tôi đặt mã này trong "models.py" của mình:

from django.db.models import signals
from django.contrib.auth.management import create_superuser
from django.contrib.auth import models as auth_app

# Prevent interactive question about wanting a superuser created.  (This
# code has to go in this otherwise empty "models" module so that it gets
# processed by the "syncdb" command during database creation.)

signals.post_syncdb.disconnect(
    create_superuser,
    sender=auth_app,
    dispatch_uid = "django.contrib.auth.management.create_superuser")

Tôi không chắc chắn về cách đảm bảo rằng mã này được chạy sau mã Django thực hiện đăng ký. Tôi đã nghĩ rằng điều đó sẽ phụ thuộc vào việc ứng dụng của bạn hoặc ứng dụng django.contrib.auth có được đề cập đầu tiên trong INSTALLED_APPS hay không, nhưng nó có vẻ hiệu quả với tôi bất kể thứ tự tôi đặt chúng. Có thể chúng được thực hiện theo thứ tự bảng chữ cái và tôi may mắn là tên ứng dụng của tôi bắt đầu bằng chữ cái muộn hơn "d"? Hay Django chỉ đủ thông minh để làm công việc của riêng mình trước, sau đó của tôi trong trường hợp tôi muốn kết hợp với cài đặt của họ? Hãy cho tôi biết nếu bạn phát hiện ra. :-)


Cuối cùng đã thực hiện điều này và thêm một hook để tự động tạo người dùng thử nghiệm của riêng tôi (nếu settings.DEBUGTrue). Cảm ơn một lần nữa!
một mọt sách được trả tiền

11

Tôi đã vượt qua tính năng này bằng cách sử dụng phía nam

Nó phải có cho bất kỳ nhà phát triển django nào.

South là một công cụ được thiết kế để giúp di chuyển các thay đổi sang trang trực tiếp mà không phá hủy thông tin hoặc cấu trúc cơ sở dữ liệu. Các thay đổi kết quả có thể được theo dõi bởi phía nam và sử dụng các tệp python đã tạo - có thể thực hiện các hành động tương tự trên cơ sở dữ liệu thay thế.

Trong quá trình phát triển, tôi sử dụng công cụ này để git theo dõi các thay đổi cơ sở dữ liệu của mình - và thực hiện thay đổi đối với cơ sở dữ liệu mà không cần phải hủy nó trước.

  1. easy_install phía nam
  2. Thêm 'nam' vào các ứng dụng đã cài đặt của bạn

Đề xuất lần đầu tiên chạy về phía nam trên một ứng dụng.

$ python manage.py schemamigration appname --init

Điều này sẽ bắt đầu phát hiện lược đồ trên ứng dụng đó.

$ python manage.py migrate appname

Điều này sẽ áp dụng các thay đổi mô hình

  • Cơ sở dữ liệu sẽ có các mô hình mới.

Thay đổi mô hình sau lần chạy đầu tiên

$ python manage.py schemamigration appname --auto

$ python manage.py migrate appname


Các mô hình sẽ thay đổi - dữ liệu không bị phá hủy. Ngoài ra phía nam còn làm được nhiều hơn thế nữa ...


9

Lưu ý: vì syncdblệnh phiên bản 1.7 không được dùng nữa . Sử dụng migrate thay thế .

Django 1.7 cũng giới thiệu AppConfig như một phương tiện tùy chỉnh quá trình khởi tạo ứng dụng.

Vì vậy, kể từ Django 1.7, cách đơn giản nhất để đạt được những gì bạn muốn là sử dụng một AppConfiglớp con của '.

Giả sử, bạn tình cờ có tài khoản riêng example_appđược thêm vào của bạn INSTALLED_APPSvà bạn muốn tạo và quản trị người dùng với mật khẩu quản trị bất cứ khi nào bạn chạy ./manage.py migratetừ đầu. Tôi cũng cho rằng tự động tạo người dùng quản trị được yêu cầu chỉ trong dev môi trường - không trong sản xuất .

Thêm mã sau vào example_app/apps.py

# example_app/apps.py

from django.apps import AppConfig
from django.conf import settings
from django.db.models.signals import post_migrate
from django.contrib.auth.apps import AuthConfig


USERNAME = "admin"
PASSWORD = "admin"


def create_test_user(sender, **kwargs):
    if not settings.DEBUG:
        return
    if not isinstance(sender, AuthConfig):
        return
    from django.contrib.auth.models import User
    manager = User.objects
    try:
        manager.get(username=USERNAME)
    except User.DoesNotExist:
        manager.create_superuser(USERNAME, 'x@x.com', PASSWORD)


class ExampleAppConfig(AppConfig):
    name = __package__

    def ready(self):
        post_migrate.connect(create_test_user)

Ngoài ra, hãy thêm tham chiếu sau vào cấu hình ứng dụng bên trong ứng dụng example_app/__init__.py:

# example_app/__init__.py

default_app_config = 'example_app.apps.ExampleAppConfig'

Trong đó default_app_config là một chuỗi Python đường dẫn đến AppConfiglớp con như được đề cập ở đây .


2
Thật không may, tính năng này không còn hoạt động như Django 1.9 vì django.contrib.authkhông còn khả dụng tại thời điểm cấu hình. Đây là do thiết kế và đã không được dùng nữa kể từ ngày 1.8 nên nó có khả năng không bao giờ quay trở lại. Thật là rất buồn ... Tôi thích bản hack này.
Adrian Petrescu

Được rồi, tôi đã tìm ra cách sửa mã của bạn để hoạt động với Django 1.9! Tôi đã chỉnh sửa câu trả lời của bạn với các bản sửa lỗi. Nhờ gửi bài cho nó :)
Adrian Petrescu

5

Các manage.py resetlệnh sẽ thiết lập lại cơ sở dữ liệu của bạn mà không phá hủy sử dụng siêu tạo của bạn. Tuy nhiên, dữ liệu cần được nhập lại.


1
đặt lại đã được thay thế bằng xả với Django 1.5 stackoverflow.com/questions/15454008/…
tjb

3

Bạn có thể sử dụng django-finalware để thực hiện việc này cho mình. Chỉ cần thêm finalwarevào của bạn INSTALLED_APPSvà bao gồm những điều sau trong settings.py:

SITE_SUPERUSER_USERNAME = 'myadmin'
SITE_SUPERUSER_EMAIL = 'myadmin@example.com'
SITE_SUPERUSER_PASSWORD  = 'mypass'  # this can be set from a secret file.

# optional object id. Ensures that the superuser id is not set to `1`.
# you can use this as a simple security feature
SITE_SUPERUSER_ID = '343'

Sau đó, chỉ cần chạy ./manage.py syncdb(Django <1.7) hoặc ./manage.py migrate(Django> = 1.7), và nó sẽ tự động tạo siêu người dùng hoặc cập nhật người dùng hiện có cho bạn.

Bạn không bao giờ được nhắc tạo siêu người dùng nữa.


Nếu nó do bạn tạo thì vui lòng thêm tuyên bố từ chối trách nhiệm
Erion S

Nó có tương thích với Django> = 2.0 không?
Dunatotatos

@Dunatotatos vâng đúng như vậy. Hỗ trợ phiên bản Django cũng có thể được tìm thấy trong tệp .travis.yml của repo
un33k

3

Kể từ Django 1.7, cách được đề xuất để điền cơ sở dữ liệu là thông qua di chuyển dữ liệu. Để tạo một di chuyển dữ liệu để tạo quản trị viên, trước tiên bạn nên tạo một di chuyển trống:

./manage.py makemigrations --empty myapp --name create-superuser

Điều này sẽ tạo ra một di chuyển trống trong myapp/migrations/000x__create-superuser.py. Chỉnh sửa tệp để làm cho tệp trông giống như sau:

# -*- coding: utf-8 -*-
from __future__ import unicode_literals

from django.db import migrations, models
from django.contrib.auth.models import User


def create_superuser(apps, schema_editor):
    User.objects.create_superuser(username='myadmin', password='mypassword', email='myemail@gmail.com')


class Migration(migrations.Migration):

    dependencies = [('myapp', '000y_my-previous-migration-file'),]

    operations = [migrations.RunPython(create_superuser)]

3

Tôi đã giải quyết việc tạo một tập lệnh python như thế này để đặt lại tất cả nội dung của mình [phiên bản cập nhật] [1.8 cũng vậy]:

import os
import sys

os.environ.setdefault("DJANGO_SETTINGS_MODULE", "main.settings.dev")

from django.conf import settings
from django.core import management
from django import get_version

PROJECT_ROOT = os.path.abspath(os.path.join(os.path.dirname(__file__), os.pardir))
if PROJECT_ROOT not in sys.path:
    sys.path.append(PROJECT_ROOT)

yn = raw_input('Are you sure you want to reset everything? (y/n) ')
if yn == 'y':

    # Drops the db / creates the db
    if settings.DATABASES['default']['ENGINE'].find('mysql') != -1:
        os.system('mysqladmin -uroot -pIronlord0 -f drop db')
        os.system('mysqladmin -uroot -pIronlord0 -f create db')
    elif settings.DATABASES['default']['ENGINE'].find('psycopg2') != -1:
        os.system('psql -U postgres -c "DROP DATABASE db"')
        os.system('psql -U postgres -c "CREATE DATABASE db WITH OWNER = admin"')
    elif settings.DATABASES['default']['ENGINE'].find('sqlite3') != -1:
        try:
            os.remove(os.path.join(PROJECT_ROOT, 'data.db'))
        except:
            pass

    # Getting application handle here otherwise db gets allocated and it can not be destroyed.
    if get_version() > '1.6.10':
        from django.core.wsgi import get_wsgi_application
        application = get_wsgi_application()

    management.call_command('syncdb', interactive=False)

    # Creates admin/password
    from django.contrib.auth.management.commands import changepassword
    management.call_command('createsuperuser', interactive=False, username="admin", email="xxx@example.com")
    command = changepassword.Command()
    command._get_pass = lambda *args: 'password'
    if get_version() >= '1.8':
        command.execute(username="admin")
    else:
        command.execute("admin")


    # Creates the default site entry
    from django.contrib.sites.models import Site
    site = Site.objects.get_current()
    site.domain = 'www.example.com'
    site.name = ' xxx '
    site.save()

Nó hoạt động như một say mê!

Tái bút: Hãy chắc chắn dừng máy chủ (thử nghiệm) của bạn ở nơi mà db ở trên phụ trách trước khi chạy tập lệnh này!


2

Hãy xem dumpdatalệnh quản lý. Ví dụ:

python manage.py dumpdata > initial_data.json

Nếu tệp này, được gọi là vật cố định, được đặt tên initial_data(.xml hoặc .json), thì syncdblệnh sẽ chọn nó và điền các bảng của bạn cho phù hợp. Nó vẫn sẽ hỏi bạn xem bạn có muốn tạo người dùng hay không, nhưng tôi tin rằng bạn có thể trả lời "không" một cách an toàn, sau đó nó sẽ điền vào cơ sở dữ liệu dựa trên lịch thi đấu của bạn.

Thông tin thêm về điều này có thể được tìm thấy trong tài liệu .


1
Bạn có thể thêm tùy chọn --noinput vào syncdb để tắt lời nhắc tương tác nếu bạn có thông tin về phiên và người dùng cấp cao trong initial_data.json
philgo 20

2

Đang phát triển với sqlite. Xóa cơ sở dữ liệu bằng cách xóa tệp. Tải quản trị viên từ đồ đạc.

change management.py (django 1.4):

# hack to prevent admin promt
if  len(sys.argv) == 2 and sys.argv[1] == 'syncdb':
    sys.argv.append('--noinput')

2
if 'syncdb' in sys.argv: sys.argv.append('--noinput')
TimP

1

Giải pháp của tôi cho điều này là không xóa các bảng xác thực đó khi xóa cơ sở dữ liệu của tôi.


1

Nếu bạn muốn nhập mã khởi tạo trực tiếp vào tệp nguồn python, mã này đã được sửa đổi management.py có thể hữu ích (và cảm ơn vì mã nhỏ của Cjkjvfnby!):

#!/usr/bin/env python
import os
import sys

if __name__ == "__main__":
    # set your django setting module here
    os.environ.setdefault("DJANGO_SETTINGS_MODULE", "app.settings") 

    from django.core.management import execute_from_command_line

    # hack to prevent admin prompt
    if len(sys.argv) == 2 and sys.argv[1] == 'syncdb':
        sys.argv.append('--noinput')

    execute_from_command_line(sys.argv)

    # additional process for creation additional user, misc data, and anything
    for arg in sys.argv:
        # if syncdb occurs and users don't exist, create them
        if arg.lower() == 'syncdb':
            print 'syncdb post process...'
            from django.contrib.auth.models import User

            admin_id = 'admin'
            admin_email = 'superuser@mail.com'
            admin_password = 'superuser_password'
            additional_users = [
                                ['tempuser', 'user_email@mail.com', 'tempuser_password']
                                ]

            # admin exists?
            user_list = User.objects.filter(username=admin_id)
            if len(user_list) == 0: 
                print 'create superuser: ' + admin_id
                new_admin = User.objects.create_superuser(admin_id, admin_email, admin_password)

            # additional user exists?
            for additional_user in additional_users:
                user_list = User.objects.filter(username=additional_user[0])
                if len(user_list) == 0: 
                    print 'create additional user: ' + additional_user[0]
                    new_admin = User.objects.create_user(additional_user[0], additional_user[1], additional_user[2])

            # any other data

Tôi chỉ hiển thị mã tạo người dùng ở đây, nhưng bạn có thể nâng cao mã này nhiều hơn như bạn muốn.


0

Tôi đang sử dụng sqlite làm cơ sở dữ liệu nhà phát triển. Sau khi thay đổi các lớp mô hình, chỉ cần thả các bảng tương ứng với trình quản lý sqlite (một plugin firefox, luôn mở để kiểm tra dữ liệu) và chạy manage.py syncdbđể tạo lại những gì còn thiếu.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.