Django menggunakan get_user_model vs pengaturan.AUTH_USER_MODEL

99

Membaca Dokumentasi Django:

get_user_model ()

Daripada merujuk ke Pengguna secara langsung, Anda harus mereferensikan model pengguna menggunakan django.contrib.auth.get_user_model (). Metode ini akan mengembalikan model Pengguna yang saat ini aktif - model Pengguna kustom jika ditentukan, atau Pengguna sebaliknya.

Saat Anda menentukan kunci asing atau relasi banyak-ke-banyak ke model Pengguna, Anda harus menentukan model kustom menggunakan pengaturan AUTH_USER_MODEL.

Saya bingung dengan teks di atas. Haruskah saya melakukan ini:

author = models.ForeignKey(settings.AUTH_USER_MODEL)

atau ini...

author = models.ForeignKey(get_user_model())

Keduanya tampaknya berhasil.

Prometheus
sumber

Jawaban:

89

Penggunaan settings.AUTH_USER_MODELakan menunda pengambilan kelas model sebenarnya hingga semua aplikasi dimuat. get_user_modelakan mencoba mengambil kelas model pada saat aplikasi Anda diimpor pertama kali.

get_user_modeltidak dapat menjamin bahwa Usermodel tersebut sudah dimuat ke dalam cache aplikasi. Ini mungkin berfungsi dalam pengaturan khusus Anda, tetapi ini adalah skenario untung-untungan. Jika Anda mengubah beberapa pengaturan (misalnya urutan INSTALLED_APPS), hal itu mungkin akan merusak impor dan Anda harus menghabiskan waktu tambahan untuk debugging.

settings.AUTH_USER_MODEL akan meneruskan string sebagai model kunci asing, dan jika pengambilan kelas model gagal pada saat kunci asing ini diimpor, pengambilan akan ditunda sampai semua kelas model dimuat ke dalam cache.

knbk
sumber
7
Secara konkret, Anda dapat mengalami masalah impor melingkar dengan model. ForignKey (get_user_model ())
Chris Clark
2
Bagian dokumen ini mengatakan "Secara umum, Anda harus mereferensikan model Pengguna dengan AUTH_USER_MODELpengaturan dalam kode yang dijalankan pada waktu impor. get_user_model()Hanya bekerja setelah Django mengimpor semua model."
Hamish Downer
7
Jadi konkretnya, dalam fungsi (tampilan, model / serializer / metode formulir), gunakan get_user_model(), untuk atribut kelas gunakan AUTH_USER_MODEL?
Nick T
53

Baru sejak Django 1.11.

Sejak Django 1.11 anda dapat menggunakan get_user_model()dalam kedua kasus! Jadi kalau tidak mau repot lagi, bawa saja.

"dalam kedua kasus" berarti: jika Anda memerlukan model pengguna untuk mengakses atributnya, serta jika Anda ingin mendefinisikan relasi ForeignKey / ManyToMany.

Dari changelog :

get_user_model () sekarang bisa dipanggil pada waktu impor, bahkan dalam modul yang mendefinisikan model.

jadi ... apakah masih ada alasan untuk menggunakan settings.AUTH_USER_MODEL? Nah, dokumen masih merekomendasikan settings.AUTH_USER_MODEL(yang merupakan string) untuk mendefinisikan relasi, tetapi tanpa memberikan alasan eksplisit. Mungkin bermanfaat untuk kinerja, tetapi tampaknya tidak terlalu menjadi masalah.

Contoh kode:

from django.db import models
from django.contrib.auth import get_user_model
...
    ...
    user = models.ForeignKey(
        get_user_model(),
        null=True, # explicitly set null, since it's required in django 2.x. - otherwise migrations will be incompatible later!
        ...
    )
Ilja
sumber
Terima kasih telah menunjukkan bahwa get_user_model()dapat dipanggil pada waktu impor; bagaimanapun, Django tetap menyarankan bahwa pengguna mendefinisikan hubungan kunci asing dan banyak ke banyak menggunakan AUTH_USER_MODEL
kevins
2
terima kasih telah menunjukkan rekomendasi ini, entah bagaimana saya mengabaikannya saat menulis balasan, tetapi sekarang saya menemukannya. Saya mencoba mengintegrasikan ini ke dalam jawaban (tetap berpihak pada get_user_model, terutama bagi pembaca yang bingung tentang perbedaannya)
Ilja
7

Sejak Django 1.11, get_user_model()sebenarnya menggunakan settings.AUTH_USER_MODEL:

def get_user_model():
    """
    Return the User model that is active in this project.
    """
    try:
        return django_apps.get_model(settings.AUTH_USER_MODEL, require_ready=False)
    except ValueError:
        raise ImproperlyConfigured("AUTH_USER_MODEL must be of the form 'app_label.model_name'")
    except LookupError:
        raise ImproperlyConfigured(
            "AUTH_USER_MODEL refers to model '%s' that has not been installed" % settings.AUTH_USER_MODEL
        )
Murey Tasroc
sumber
0

settings.AUTH_USER_MODEL mengembalikan string (lokasi model Pengguna) misalnya 'user_accounts.User'

get_user_model () mengembalikan kelas model ACTUAL, bukan string.

Jadi dalam kasus di mana Anda membutuhkan model User, gunakan get_user_model (). Jika Anda membutuhkan lokasinya (module.model sebagai string), gunakan pengaturan.AUTH_USER_MODEL.

ImportError
sumber
-11

Cara untuk kembali ke model pengguna default jika AUTH_USER_MODEL tidak disetel:

from django.conf import settings
from django.contrib.auth.models import User

USER_MODEL = getattr(settings, 'AUTH_USER_MODEL', User)
synw
sumber
7
AUTH_USER_MODELsudah memiliki default, jadi akan selalu disetel.
knbk
4
pengaturan.AUTH_USER_MODEL juga merupakan string dan fallback Anda Useradalah model
Matt