2014-06-16 14 views
-2

나는 장고 인증 시스템을 배우려고하고 있는데 몇 가지 질문이 있습니다.Django 여러 사용자, 백엔드 및 일반보기

이메일 인증을 통해 여러 사용자를 만들고 싶습니다. 그래서, 나는 AbtractBaseUserAbtractBaseManager을 사용했다. 나는 장고 의사와 웹 사이트에서이 질문을 읽었습니다 : Implementing multiple user types with Django 1.5

그리고 그것을 사용하고 싶습니다. 그래서 두 번째 요점을 구현하려고합니다. 두 개의 사용자 유형에 대한 모든 필드는 1 개의 모델에 있고 user_type 변수로는 표시 할 필드를 선택할 수 있습니다. 내 코드는 아래 다음과 같습니다 :

models.py

# -*- coding: utf-8 -*- 

from django.db import models 
from django.conf import settings 
from django.utils.translation import ugettext_lazy as _ 
from django.contrib.auth.models import (
    BaseUserManager, AbstractBaseUser 
) 

TYPE_USER = (
    ('student', _('Student')), 
    ('employee', _('Employee')), 
) 

class MyuserManager(BaseUserManager): 
    def create_user(self, email, last_name, first_name, date_of_birth, user_type, password=None): 
     if not email: 
      raise ValueError("users must have an email address") 

     user = self.model(
      email   = self.normalize_email(email), 
      last_name  = last_name, 
      first_name = first_name, 
      date_of_birth = date_of_birth, 
      user_type  = user_type, 
     ) 

     user.set_password(password) 
     user.save() 
     return user 

    def create_superuser(self, email, password, last_name, first_name, date_of_birth, user_type): 
     user = self.create_user(email, 
      password  = password, 
      date_of_birth = date_of_birth, 
      last_name  = last_name, 
      first_name = first_name, 
      user_type  = user_type, 
     ) 
     user.is_admin = True 
     user.is_staff = True 
     user.save() 
     return user 

class MyUser(AbstractBaseUser): 
    """Based model user""" 
    email = models.EmailField(
     verbose_name = 'email', 
     max_length=255, 
     unique=True, 
    ) 
    last_name  = models.CharField(max_length=30) 
    first_name = models.CharField(max_length=30) 
    date_of_birth = models.DateField() 
    user_type  = models.CharField(_('Type'), choices=TYPE_USER, max_length=20, default='student') 
    phone   = models.CharField(max_length=20, blank=True) 
    friends  = models.ManyToManyField("self", blank=True) 
    faculty  = models.ForeignKey(Faculty, null=True, blank=True) 
    desk   = models.CharField(max_length=30, blank=True) 
    campus  = models.ForeignKey(Campus, null=True, blank=True) 
    job   = models.ForeignKey(Function, null=True, blank=True) 
    cursus  = models.ForeignKey(Cursus, null=True, blank=True) 
    year   = models.IntegerField(null=True, blank=True) 
    is_active  = models.BooleanField(default=True) 
    is_admin  = models.BooleanField(default=False) 
    is_staff  = models.BooleanField(default=False) 

    objects = MyuserManager() 
    USERNAME_FIELD = 'email' 
    REQUIRED_FIELDS = ['last_name', 'first_name', 'date_of_birth', 'user_type'] 

질문 : 당신은 올바른 생각하십니까? 또는 공통 필드가있는 클래스 1 개와 고유 한 유형의 사용자 2 개 클래스를 만들어야합니까?

다음, 내가 그래서 난 내 프로젝트에 backend.py 파일을 구현하는 내 자신의 백엔드를 사용하고자하는

backend.py

from fbLike.models import MyUser 
from django.contrib.auth.backends import ModelBackend 


class EmailAuthBackend(ModelBackend): 
    def authenticate(self, email=None, password=None, **kwargs): 
     try: 
      user = MyUser.objects.get(email=email) 
      if user.check_password(password): 
       return user 
     except MyUser.DoesNotExist: 
      return None 

    def get_user(self, user_id): 
     try: 
      return MyUser.objects.get(pk=user_id) 
     except: 
      return None 

나를 위해, 즉 올바른 것 같다 이행.

질문 : 그러나 어떻게 멀티 테이블 상속을 진행 하시겠습니까? 그것은 가능한가? 내 models.py, backend.py으로,

class BaseUser(AbstractBaseUser): 
    email = models.EmailField(max_length=254, unique=True) 
    # common fields 


class Student(BaseUser): 
    first_name = models.CharField(max_length=30) 
    last_name = models.CharField(max_length=30) 
    # ... 


class employee(BaseUser): 
    company_name = models.CharField(max_length=100) 
    # ... 

마지막으로 내가 내 views.py에서 CRUD 시스템을 사용하려고 할 것입니다 : 내가 어떻게 예를 들어이 있는지 확인 암호 전에 사용자의 유형이 무엇인지 알고 사용자를 생성하고 업데이트하십시오. 내 파일 아래

:

forms.py 여기

class StudentProfileForm(forms.ModelForm): 
    phone = forms.CharField(required=True) 
    faculty = forms.ModelChoiceField(Faculty.objects.all()) 
    campus = forms.ModelChoiceField(Campus.objects.all()) 
    cursus = forms.ModelChoiceField(Cursus.objects.all()) 
    year = forms.IntegerField(required=True) 

    class Meta: 
     model = MyUser 
     fields = ('email', 'password', 'first_name', 'last_name', 
        'date_of_birth', 'phone', 'faculty', 'campus', 'cursus', 'year' 
     ) 
     widgets = { 
      'password': forms.PasswordInput(render_value=True), 
     } 

class EmployeeProfileForm(forms.ModelForm): 
    date_of_birth = forms.DateField(widget = AdminDateWidget) 
    phone = forms.CharField(required=True) 
    faculty = forms.ModelChoiceField(Faculty.objects.all()) 
    campus = forms.ModelChoiceField(Campus.objects.all()) 
    job = forms.ModelChoiceField(Function.objects.all()) 
    desk = forms.IntegerField(required=True) 

    class Meta: 
     model = MyUser 
     fields = ('email', 'password', 'first_name', 'last_name', 
        'date_of_birth', 'phone', 'faculty', 'campus', 'job', 'desk' 
     ) 
     widgets = { 
      'password': forms.PasswordInput(render_value=True), 
     } 

, 나는 그것이 너무 복잡하다고 생각하지만 난 복잡성을 감소하는 방법을 모르겠어요.

views.py

class RegisterProfile(CreateView): 
    model = MyUser 
    template_name = 'fbLike/user_profile.html' 
    form_class = StudentProfileForm 
    second_form_class = EmployeeProfileForm 

    def get_object(self): 
     return super(RegisterProfile, self).get_object() 

    def get_success_url(self): 
     return reverse('login',) 

    def get_context_data(self, **kwargs): 
     context = super(RegisterProfile, self).get_context_data(**kwargs) 
     if 'studenForm' not in context: 
      context['studentForm'] = self.form_class 
     if 'employeeForm' not in context: 
      context['employeeForm'] = self.second_form_class 
     return context 


    def form_valid(self, form): 
     self.object = MyUser.objects.create_user(**form) 
     return super(RegisterProfile, self).form_valid(form) 

    def form_invalid(self, form): 
     return super(RegisterProfile, self).form_invalid(form) 

    def post(self, request, *args, **kwargs): 
     self.object = None 
     if request.POST['profileType'] == 'student': 
      form = self.form_class(request.POST, prefix='st') 
      form.user_type = 'student' 
     else: 
      form = self.second_form_class(request.POST, prefix='em') 
      form.user_type = 'employee' 

     if form.is_valid(): 
      return self.form_valid(form) 
     else: 
      return self.form_invalid(form) 


class UpdateProfile(UpdateView): 
    model = MyUser 
    template_name = 'fbLike/modify_profile.html' 

    def get_form_class(self): 
     if self.request.user.user_type == 'student': 
      return StudentProfileForm 
     return EmployeeProfileForm 

    def get_success_url(self): 
     return reverse('welcome',) 

다음 -createProfile, 나는 내가 올바른 양식을 선택할 수에 javscript 내 템플릿 덕분에이 양식을 보내드립니다. 하지만 양식을 제출하면 사용자 비밀번호에 오류가 있습니다. 관리자 페이지에서 내 사용자를 확인하면 hashpassword 시스템이 실패한 것 같습니다. 그래서, 내 첫 번째 시도는 해결 : request.user.set_password를 사용하기 위해 내 양식에 save 메소드를 대체하는 것이지만 작동하지 않습니다.

나는 오랜 설명을 알고있다. 하지만 모두들 2 개의 폼으로 CreateView 클래스의 예를 들어 줄 수 있나요? 클래스를 사용할 수 없다면이 함수를 어떻게 구현할 수 있습니까?

나는 미래에 미리

+0

[this] (http://stackoverflow.com/help/dont-ask)를 읽으십시오. –

답변

2

나는 당신의 여러 질문에 대답하려고 시도에 감사하지만, 제발 - 포스트 당 하나 개의 질문을. 나는 당신이 새로운 것을 알았지 만, StackOverflow는 토론 포럼이 아니며, asking questions의 섹션 인 도움말 섹션 (각 페이지 하단의 링크)을 살펴보십시오.


나는 이메일 인증 여러 사용자를 만들려고합니다. [...] 당신이 그것이 옳다고 생각하니? 또는 공통 필드가 하나 인 클래스를 작성해야합니까? 및 고유 한 유형의 사용자를위한 2 개의 클래스가 있습니까?

올바른지 확인하십시오. 이러한 종류의 질문은 codereview.stackexchange.com에 더 적합합니다. 특히 버그가 없으므로 특히 그렇습니다.

그러나 어떻게 다중 테이블 상속을 진행 하시겠습니까? 그것은 가능한가? 내가 예를 들어 이있는 경우 [...] 먼저

, 인증 백엔드는 전혀 다른 주제는 체크인 암호 전에 사용자의 유형이 무엇인지 알 수있는 방법 ; 그들은 다중 테이블 상속과 관련이 없습니다 (나는 당신이 관계 또는 다중 사용자 프로파일을 의미한다고 생각합니다).

암호 인증 알고리즘이 각 사용자 유형마다 다른 경우 여러 인증 백엔드 만 필요합니다. 모든 사용자 암호가 동일한 위치/시스템/데이터베이스에 저장되면 다중 인증 백엔드가 필요하지 않습니다.

사용자 유형을 반환하는 기본 사용자 클래스에 메서드를 구현해야합니다. 그런 다음 user_passes_check decorator을 사용하여보기에서 액세스를 제한 할 수 있습니다.

당신은 내가 무슨 생각을 달성 할이 방법은 당신이 내 models.py으로,

마지막으로 등, "학생들 만이 섹션"후 무엇이며, backend.py은 내가 사용하려고 것이다 내 views.py에있는 CRUD 시스템은 사용자를 생성하고 업데이트합니다. [..] 여기서는 너무 복잡하다고 생각하지만 복잡성을 줄이는 방법을 모르겠습니다.

ModelForm에서 모델의 모든 필드를 반복하지 않아도됩니다. 필드를 수정해야 할 경우 필드를 재정의하거나 추가 "비 모델"필드를 양식에 추가하기 만하면됩니다. 이 같은 간단한 ModelForm으로 시작할 수 있습니다

class UserForm(forms.ModelForm): 
    class Meta: 
     model = User 
     fields = ('name', 'email', 'password') 

추가 필드를 추가하는 일반적인 용도는 별도의 암호 필드를함으로써, 암호 확인을 요청하는 것입니다.

CreateProfile의 경우 템플릿에 2 개의 양식을 보내고 javscript 덕분에 올바른 양식을 선택할 수 있습니다. 하지만 양식을 제출하면 사용자 비밀번호에 오류가 있습니다. 관리자 페이지에서 내 사용자를 확인하면 hashpassword 시스템이 실패한 것 같습니다. 그래서, 내 먼저 해결하려고 : 그것은 내 양식에 저장 방법을 로 재정의하는 것이 었습니다. request.user.set_password를 사용하지만 작동하지 않습니다.

form wizard을 사용하여 여러 단계의 등록 프로세스를 구현하십시오. 첫 번째 단계에서는 생성 할 기본 정보와 계정 유형을 묻습니다. 두 번째 단계에서는 두 가지 양식을 보내고 자바 스크립트를 사용하여 관련 양식을 보내지 않고 관련 양식 만 보냅니다.

set_password을 사용하는 코드에는 아무 것도 표시되지 않으므로 두 번째 부분에 대해서는 언급 할 수 없습니다.