Naudotojo modelio išplėtimas pritaikytais laukais Django

Koks yra geriausias būdas išplėsti naudotojo modelį (sujungtą su „Django“ autentifikavimo programa) su priskirtais laukais? Taip pat norėčiau naudoti el. Laišką kaip naudotojo vardą (autentifikavimo tikslais).

Jau mačiau keletą būdų tai padaryti, bet jūs negalite nuspręsti, kuris iš jų yra geresnis.

352
04 сент. nustatyta Farinha 04 sept. 2008-09-04 19:19 '08, 19:19 PM 2008-09-04 19:19
@ 9 atsakymai

Mažiausiai skausmingas ir tikrai rekomenduojamas būdas tai padaryti yra „ OneToOneField(User) nuosavybė.

Išplėsti esamą naudotojo modelį

hellip;

Jei norite išsaugoti su vartotoju susijusią informaciją, galite naudoti „ vienas su vienu“ ryšį su modeliu, kuriame yra laukų, kad gautumėte daugiau informacijos. Šis „vienas su vienu“ modelis dažnai vadinamas profilio modeliu, nes jis gali saugoti informaciją, nesusijusį su autoriaus informacija apie svetainės naudotoją.

Tačiau django.contrib.auth.models.User pratęsimas ir django.contrib.auth.models.User taip pat veikia ...

Vartotojo modelio peržiūra

Kai kurie projektai gali turėti autentifikavimo reikalavimus, kuriems ne visada tinkamas Djangos User modelis. Pavyzdžiui, kai kuriose svetainėse tikslinga naudoti el. Pašto adresą kaip identifikavimo raktą vietoj naudotojo vardo.

[Ed: du įspėjimai ir pranešimas , pažymėdami, kad tai yra gana stiprus .]

Aš tikrai nenoriu keisti jūsų Django šaltinio medžio naudotojo klasės ir (arba) kopijuoti ir keisti auth modulį.

200
04 сент. atsakymą pateikė Ryan Duffield 04 sept. 2008-09-04 20:02 '08 at 8:02 pm 2008-09-04 20:02

Pastaba: šis atsakymas yra pasenęs. žr. kitus atsakymus, jei naudojate Django 1.7 ar naujesnę.

Taip aš tai darau.

 #in models.py from django.contrib.auth.models import User from django.db.models.signals import post_save class UserProfile(models.Model): user = models.OneToOneField(User) #other fields here def __str__(self): return "%s profile" % self.user def create_user_profile(sender, instance, created, **kwargs): if created: profile, created = UserProfile.objects.get_or_create(user=instance) post_save.connect(create_user_profile, sender=User) #in settings.py AUTH_PROFILE_MODULE = 'YOURAPP.UserProfile' 

Taip bus sukurtas individualus failas kiekvieną kartą, kai naudotojas bus išsaugotas. Tada galite naudoti

  user.get_profile().whatever 

Čia rasite daugiau informacijos iš dokumentacijos.

http://docs.djangoproject.com/en/dev/topics/auth/#storing-additional-information-about-users

Atnaujinimas: Atkreipkite dėmesį: AUTH_PROFILE_MODULE pasenusi nuo versijos v1.5 versijos: https://docs.djangoproject.com/en/1.5/ref/settings/#auth-profile-module

212
08 июня '09 в 19:53 2009-06-08 19:53 atsakymą pateikė Raisins birželio 08 d. 09:19:53 2009-06-08 19:53

Na, šiek tiek praėjo nuo 2008 m., Ir atėjo laikas naujam atsakymui. Naudodami „Django 1.5“ galite sukurti pasirinktinę klasę. Tiesą sakant, kai rašiau tai, jis jau buvo sujungtas su kapitonu, todėl galite jį išbandyti.

Yra keletas informacijos apie tai dokumentuose , arba jei norite į ją įsiskverbti, tai įsipareigoja .

Viskas, ką jums reikia padaryti, yra pridėti „ AUTH_USER_MODEL prie nustatymų, naudodami kelią į vartotojo naudotojų klasę, kuri išplečia „ AbstractBaseUser (labiau pritaikomą versiją) arba „ AbstractUser (daugiau ar mažiau senų vartotojų klasių, kurias galite pratęsti).

Žmonėms, kurie yra tingūs spustelėję, čia yra pavyzdinis kodas (paimtas iš dokumentų ):

 from django.db import models from django.contrib.auth.models import ( BaseUserManager, AbstractBaseUser ) class MyUserManager(BaseUserManager): def create_user(self, email, date_of_birth, password=None): """ Creates and saves a User with the given email, date of birth and password. """ if not email: raise ValueError('Users must have an email address') user = self.model( email=MyUserManager.normalize_email(email), date_of_birth=date_of_birth, ) user.set_password(password) user.save(using=self._db) return user def create_superuser(self, username, date_of_birth, password): """ Creates and saves a superuser with the given email, date of birth and password. """ u = self.create_user(username, password=password, date_of_birth=date_of_birth ) u.is_admin = True u.save(using=self._db) return u class MyUser(AbstractBaseUser): email = models.EmailField( verbose_name='email address', max_length=255, unique=True, ) date_of_birth = models.DateField() is_active = models.BooleanField(default=True) is_admin = models.BooleanField(default=False) objects = MyUserManager() USERNAME_FIELD = 'email' REQUIRED_FIELDS = ['date_of_birth'] def get_full_name(self): # The user is identified by their email address return self.email def get_short_name(self): # The user is identified by their email address return self.email def __unicode__(self): return self.email def has_perm(self, perm, obj=None): "Does the user have a specific permission?" # Simplest possible answer: Yes, always return True def has_module_perms(self, app_label): "Does the user have permissions to view the app `app_label`?" # Simplest possible answer: Yes, always return True @property def is_staff(self): "Is the user a member of staff?" # Simplest possible answer: All admins are staff return self.is_admin 
175
29 сент. Atsakymas pateikiamas Ondrej Slinták 29 sep . 2012-09-29 01:22 '12 at 1:22 am 2012-09-29 01:22

Yra oficiali rekomendacija saugoti papildomą informaciją apie vartotojus . Django knygoje taip pat aptariama ši problema skyriuje „ Profiliai“ .

40
04 сент. Atsakymą pateikė Dmitrijus Mukhin 04 sep . 2008-09-04 19:35 '08 at 7:35 pm 2008-09-04 19:35

Naudodami „Django 1.5“, galite lengvai išplėsti naudotojo modelį ir išsaugoti vieną lentelę duomenų bazėje.

 from django.contrib.auth.models import AbstractUser from django.db import models from django.utils.translation import ugettext_lazy as _ class UserProfile(AbstractUser): age = models.PositiveIntegerField(_("age")) 

Taip pat turite konfigūruoti jį kaip dabartinę pasirinktinę klasę nustatymų faile.

 # supposing you put it in apps/profiles/models.py AUTH_USER_MODEL = "profiles.UserProfile" 

Jei norite pridėti daug vartotojų nuostatų, „OneToOneField“ parinktis gali būti geriausias pasirinkimas.

Pastaba žmonėms, besivystantiems trečiųjų šalių bibliotekomis: jei reikia prieiti prie vartotojų klasės, nepamirškite, kad žmonės gali jį pakeisti. Norėdami gauti norimą klasę, naudokite oficialų asistentą.

 from django.contrib.auth import get_user_model User = get_user_model() 
36
21 апр. Riccardo Galli atsakymas balandžio 21 d 2013-04-21 00:56 '13, 0:56, 2013-04-21 00:56

Žemiau pateikiamas kitoks požiūris į vartotojo išplėtimą. Manau, kad tai yra aiškesnis, paprastesnis, suprantamesnis, o po to abu požiūriai.

http://scottbarnham.com/blog/2008/08/21/extending-the-django-user-model-with-inheritance/

Naudojant pirmiau pateiktą metodą:

  • Jums nereikia naudoti user.get_profile (). newattribute, kad gautumėte papildomą informaciją, susijusią su vartotoju
  • galite tiesiogiai pasiekti papildomų naujų atributų naudodami user.newattribute
20
01 апр. Atsakymą pateikė Rama Vadakattu. 2009-04-01 16:01 '09 ne 16:01 2009-04-01 16:01

Jūs galite tiesiog išplėsti vartotojo profilį kurdami naują įrašą kiekvieną kartą, kai vartotojas sukuriamas naudojant „Django“ pranešimo išsaugojimo signalus.

models.py

 from django.db.models.signals import * from __future__ import unicode_literals class userProfile(models.Model): userName = models.OneToOneField(User, related_name='profile') city = models.CharField(max_length=100, null=True) def __unicode__(self): # __str__ return unicode(self.userName) def create_user_profile(sender, instance, created, **kwargs): if created: userProfile.objects.create(userName=instance) post_save.connect(create_user_profile, sender=User) 

Kai bus sukurtas naujas vartotojas, tai automatiškai sukurs darbuotojo egzempliorių.

Jei norite išplėsti savo naudotojo modelį ir norite sukurti papildomą informaciją kurdami vartotoją, galite naudoti django-betterforms ( http://django-betterforms.readthedocs.io/en/latest/multiform.html ). Taip bus sukurta vartotojo pridėjimo forma su visais naudotojoProfilio modelio laukais.

models.py

 from django.db.models.signals import * from __future__ import unicode_literals class userProfile(models.Model): userName = models.OneToOneField(User) city = models.CharField(max_length=100) def __unicode__(self): # __str__ return unicode(self.userName) 

form.py

 from django import forms from django.forms import ModelForm from betterforms.multiform import MultiModelForm from django.contrib.auth.forms import UserCreationForm from .models import * class profileForm(ModelForm): class Meta: model = Employee exclude = ('userName',) class addUserMultiForm(MultiModelForm): form_classes = { 'user':UserCreationForm, 'profile':profileForm, } 

peržiūros.py

 from django.shortcuts import redirect from .models import * from .forms import * from django.views.generic import CreateView class addUser(CreateView): form_class = addUserMultiForm template_name = "addUser.html" success_url = '/your url after user created' def form_valid(self, form): user = form['user'].save() profile = form['profile'].save(commit=False) profile.userName = User.objects.get(username= user.username) profile.save() return redirect(self.success_url) 

addUser.html

 <!DOCTYPE html> <html > 

urls.py

 from django.conf.urls import url, include from appName.views import * urlpatterns = [ url(r'^add-user/$', addUser.as_view(), name='addDistributor'), ] 
8
25 июня '16 в 6:09 2016-06-25 06:09 atsakymą pateikė Atul Yadav birželio 16 d. 16:09 2016-06-25 06:09

Django vartotojo modelio plėtinys (UserProfile), pavyzdžiui, „Pro“

Radau tai labai naudinga: nuoroda

Poveikis:

iš django.contrib.auth.models importuoti vartotoją

 class Employee(models.Model): user = models.OneToOneField(User) department = models.CharField(max_length=100) >>> u = User.objects.get(username='fsmith') >>> freds_department = u.employee.department 
6
13 апр. Massimo Variolo atsakymas, pateiktas balandžio 13 d 2016-04-13 11:09 '16 at 11:09 2016-04-13 11:09

Naujas „Django 1.5“, dabar galite sukurti savo pasirinktinį naudotojo modelį (kuris šiuo atveju atrodo gerai). Žr. „Autentifikavimo konfigūravimas„ Django “

Greičiausiai nauja versija 1.5 versijoje.

1
12 марта '13 в 13:01 2013-03-12 13:01 Chantyal atsakymą pateikė kovo 13 d. 13:01 2013-03-12 13:01

Peržiūrėkite kitus klausimus apie „ žymes arba užduokite klausimą