voy a suponer que ya tienen nociones de python y django, y voy a ir directo al grano.
ya creado nuestro proyecto. creamos una app.
python manage.py startapp usuarios
y ingresamos al directorio nuevo y creamos una archivo.
touch admin.py
nos quedaría un directorio de la siguiente manera.
apps/usuarios/
├── admin.py
├── form.py
├── __init__.py
├── models.py
├── tests.py
└── views.py
editamos el archivo models.py y creamos nuestro modelos para el usuario. en tal caso yo cree el mio con la siguiente informacion.
from django.utils import timezone from django.contrib.auth.models import AbstractBaseUser, BaseUserManager, PermissionsMixin from django.contrib.auth.models import UserManager from django.db import models class Usuarios(AbstractBaseUser, PermissionsMixin): username = models.CharField(max_length=254, unique=True, db_index=True) first_name = models.CharField(max_length=30, blank=True) last_name = models.CharField(max_length=30, blank=True) email = models.EmailField(verbose_name='correo electronico', max_length=255, unique=True, db_index=True) is_active = models.BooleanField(default=True) is_admin = models.BooleanField(default=False) is_staff = models.BooleanField() es_sub_admin = models.BooleanField() es_reseller = models.BooleanField() es_cliente = models.BooleanField() date_joined = models.DateTimeField() date_of_birth = models.DateField(blank=True, null=True) objects = UserManager() USERNAME_FIELD = 'username' REQUIRED_FIELDS = ['email'] 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
una breve explicación del código anterior.
AbstractBaseUser: Proporciona la implementación base de un modelo de usuario, incluyendo contraseñas hash y tokenized restablece la contraseña.
BaseUserManager: Es un gestor personalizado para su modelo de usuario. Si su modelo de usuario define username, email, is_staff, is_active, is_superuser, last_login y campos date_joined lo mismo que el modelos User de Django, puede usar sólo UserManager de Django
PermissionsMixin: Para que sea más fácil incluir marco permiso de Django en su propia clase de usuario, Django proporciona PermissionsMixin. Este es un modelo abstracto que puede incluir en la jerarquía de clases para su modelo de usuario, que le da todos los métodos y campos de base de datos necesarios para apoyar modelo de permiso de Django. pero si quiere utilizar tus propios métodos para permisos lo puede crear sin ningún problema.
UserManager: También debe definir un gestor personalizado para su modelo de usuario. Si su modelo de usuario define nombre de usuario, correo electrónico, is_staff, is_active, is_superuser, last_login y campos date_joined lo mismo que de Django por defecto del usuario, puede instalar sólo UserManager de Django, sin embargo, si el modelo de usuario define los diferentes campos, tendrá que definir una gestor personalizado que se extiende BaseUserManage.
los campos, username, email, password, is_staff, is_superuser, is_active,
date_joined, first_name, last_name. Son necesarios para poder iniciar la sesión del administrador de django y no complicarnos la vida.
es_sub_admin, es_reseller, es_cliente, date_of_birth esto campos son agregamos a mi gusto, lo mismo pueden hacer ustedes.
USERNAME_FIELD = 'username' , definimos cual va ha ser el campo del username, podemos utilizar email, first_name o un campo nuevo como nombre_de_usuario, puede ser un campo de texto que se encuentre dentro del modelos que estamos creando.
REQUIRED_FIELDS = ['email'] , definimos los campos requeridos para la creación del usuario.
Guardamos nuestro modelo y abrimos admin.py e ingresamos el siguente codigo. este archivo fue copiado de django.contrib.auth, con unos pequeños retoques. para que funcione con nuestro modelo.
from django.db import transaction from django.conf import settings from django.contrib import admin from django.contrib.auth.forms import (UserCreationForm, AdminPasswordChangeForm) from django.contrib.auth.models import User, Group from django.contrib import messages from django.core.exceptions import PermissionDenied from django.http import HttpResponseRedirect, Http404 from django.shortcuts import get_object_or_404 from django.template.response import TemplateResponse from django.utils.html import escape from django.utils.decorators import method_decorator from django.utils.translation import ugettext, ugettext_lazy as _ from django.views.decorators.csrf import csrf_protect from django.views.decorators.debug import sensitive_post_parameters from django import forms from django.contrib.auth.forms import ReadOnlyPasswordHashField from apps.usuarios.models import Usuarios csrf_protect_m = method_decorator(csrf_protect) sensitive_post_parameters_m = method_decorator(sensitive_post_parameters()) class UserCreationForm(forms.ModelForm): """A form for creating new users. Includes all the required fields, plus a repeated password.""" password1 = forms.CharField(label='Password', widget=forms.PasswordInput) password2 = forms.CharField(label='Password confirmation', widget=forms.PasswordInput) class Meta: model = Usuarios fields = ('username', 'email', 'date_of_birth') def clean_password2(self): # Check that the two password entries match password1 = self.cleaned_data.get("password1") password2 = self.cleaned_data.get("password2") if password1 and password2 and password1 != password2: raise forms.ValidationError("Passwords don't match") return password2 def save(self, commit=True): # Save the provided password in hashed format user = super(UserCreationForm, self).save(commit=False) user.set_password(self.cleaned_data["password1"]) if commit: user.save() return user class UserChangeForm(forms.ModelForm): """A form for updating users. Includes all the fields on the user, but replaces the password field with admin's password hash display field. """ password = ReadOnlyPasswordHashField() class Meta: model = Usuarios def clean_password(self): # Regardless of what the user provides, return the initial value. # This is done here, rather than on the field, because the # field does not have access to the initial value return self.initial["password"] class UserAdmin(admin.ModelAdmin): add_form_template = 'admin/auth/user/add_form.html' change_user_password_template = None fieldsets = ( (None, {'fields': ('username', 'password')}), (_('Personal info'), {'fields': ('first_name', 'last_name', 'email')}), (_('Permissions'), {'fields': ('is_active', 'is_staff', 'is_superuser', 'is_admin', 'es_sub_admin', 'es_reseller', 'es_cliente', 'groups', 'user_permissions',)}), (_('Important dates'), {'fields': ('last_login', 'date_joined', 'date_of_birth')}), ) add_fieldsets = ( (None, { 'classes': ('wide',), 'fields': ('username', 'password1', 'password2')} ), ) form = UserChangeForm add_form = UserCreationForm change_password_form = AdminPasswordChangeForm list_display = ('username', 'email', 'first_name', 'last_name', 'is_staff',) list_filter = ('is_staff', 'is_superuser', 'is_active', 'groups') search_fields = ('username', 'first_name', 'last_name', 'email') ordering = ('username',) filter_horizontal = ('groups', 'user_permissions',) def get_fieldsets(self, request, obj=None): if not obj: return self.add_fieldsets return super(UserAdmin, self).get_fieldsets(request, obj) def get_form(self, request, obj=None, **kwargs): """ Use special form during user creation """ defaults = {} if obj is None: defaults.update({ 'form': self.add_form, 'fields': admin.util.flatten_fieldsets(self.add_fieldsets), }) defaults.update(kwargs) return super(UserAdmin, self).get_form(request, obj, **defaults) def get_urls(self): from django.conf.urls import patterns return patterns('', (r'^(\d+)/password/$', self.admin_site.admin_view(self.user_change_password)) ) + super(UserAdmin, self).get_urls() def lookup_allowed(self, lookup, value): # See #20078: we don't want to allow any lookups involving passwords. if lookup.startswith('password'): return False return super(UserAdmin, self).lookup_allowed(lookup, value) @sensitive_post_parameters_m @csrf_protect_m @transaction.commit_on_success def add_view(self, request, form_url='', extra_context=None): # It's an error for a user to have add permission but NOT change # permission for users. If we allowed such users to add users, they # could create superusers, which would mean they would essentially have # the permission to change users. To avoid the problem entirely, we # disallow users from adding users if they don't have change # permission. if not self.has_change_permission(request): if self.has_add_permission(request) and settings.DEBUG: # Raise Http404 in debug mode so that the user gets a helpful # error message. raise Http404( 'Your user does not have the "Change user" permission. In ' 'order to add users, Django requires that your user ' 'account have both the "Add user" and "Change user" ' 'permissions set.') raise PermissionDenied if extra_context is None: extra_context = {} username_field = self.model._meta.get_field(self.model.USERNAME_FIELD) defaults = { 'auto_populated_fields': (), 'username_help_text': username_field.help_text, } extra_context.update(defaults) return super(UserAdmin, self).add_view(request, form_url, extra_context) @sensitive_post_parameters_m def user_change_password(self, request, id, form_url=''): if not self.has_change_permission(request): raise PermissionDenied user = get_object_or_404(self.queryset(request), pk=id) if request.method == 'POST': form = self.change_password_form(user, request.POST) if form.is_valid(): form.save() msg = ugettext('Password changed successfully.') messages.success(request, msg) return HttpResponseRedirect('..') else: form = self.change_password_form(user) fieldsets = [(None, {'fields': list(form.base_fields)})] adminForm = admin.helpers.AdminForm(form, fieldsets, {}) context = { 'title': _('Change password: %s') % escape(user.get_username()), 'adminForm': adminForm, 'form_url': form_url, 'form': form, 'is_popup': '_popup' in request.REQUEST, 'add': True, 'change': False, 'has_delete_permission': False, 'has_change_permission': True, 'has_absolute_url': False, 'opts': self.model._meta, 'original': user, 'save_as': False, 'show_save': True, } return TemplateResponse(request, self.change_user_password_template or 'admin/auth/user/change_password.html', context, current_app=self.admin_site.name) def response_add(self, request, obj, post_url_continue=None): """ Determines the HttpResponse for the add_view stage. It mostly defers to its superclass implementation but is customized because the User model has a slightly different workflow. """ # We should allow further modification of the user just added i.e. the # 'Save' button should behave like the 'Save and continue editing' # button except in two scenarios: # * The user has pressed the 'Save and add another' button # * We are adding a user in a popup if '_addanother' not in request.POST and '_popup' not in request.POST: request.POST['_continue'] = 1 return super(UserAdmin, self).response_add(request, obj, post_url_continue) admin.site.register(Usuarios, UserAdmin)
Este le proporciona el form para crear y editar usuarios al que ya estamos acostumbrados con django, pueden agregar, quitar campos que quieran que se vean cuando se cree un usuario, cuando se modifique un usuario o los filtros necesario para los usuarios.
para terminar editarmos el setting.py de nuestro proyecto.
y agregamos la siguiente linea
AUTH_USER_MODEL = 'usuarios.Usuarios'
y queda todo listo para funcionar con el nuevo modelo personalizado para usuarios. con esto podemos tener nuestro perfil de usuario en el mismo modelos del usuario.
para asignar ForeignKey debes importa la configuración de nuestro proyecto. seria de la siguente manera.
from django.db import models
from django.conf import settings
class Balance(models.Model): """ Historial de cargas y deducciones del usuario """ fecha = models.DateTimeField(auto_now_add=True, blank=True) usuario = models.ForeignKey(settings.AUTH_USER_MODEL) def __str__(self): return self.usuario class Meta: db_table = 'balance'
Al terminar todas las modificaciones sincronizamos nuestra base de datos.
python manage.py syncdb
deja tu comentario si tienes alguna duda o sugerencia.
No hay comentarios.:
Publicar un comentario