Различные пользовательские профили с Django-профилями и Django-регистрацией

StackOverflow https://stackoverflow.com/questions/3772556

Вопрос

Мои модели .py:

USER_TYPES = (                                                                                                                                                                   
    ('D', 'Demo'   ),                                                                                                                                                               
    ('F', 'Free'   ),
    ('P', 'Premium'),                                                                                                                                                        
)                                                                                                                                                                                                                                                                                                                                                                

class BaseProfile(models.Model):                                                                                                                                                 
    user      = models.OneToOneField(User, primary_key=True)                                                                                                                     
    user_type = models.CharField(max_length=1, blank=True, choices=USER_TYPES)                                                                                                           

class DemoProfile(models.Model):                                                                                                                                                 
    user      = models.OneToOneField(User, primary_key=True)                                                                                                                     
    demo      = models.CharField(max_length=10, blank=True) 
    ...

class FreeProfile(models.Model):                                                                                                                                                 
    user      = models.OneToOneField(User, primary_key=True)                                                                                                                     
    free      = models.CharField(max_length=10, blank=True) 
    ...

class PremiumProfile(models.Model):                                                                                                                                                 
    user      = models.OneToOneField(User, primary_key=True)                                                                                                                     
    premium    = models.CharField(max_length=10, blank=True) 
    ...

class ProxyProfile(BaseProfile):                                                                                                                                                 
    class Meta:                                                                                                                                                                  
        proxy = True             
    def get_profile(self):                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     
        if self.user_type == 'D':                                                                                                                                              
            return DemoProfile._default_manager.get(user__id__exact=self.user_id)                                                                                              
        elif self.user_type == 'F':                                                                                                                                            
            return FreeProfile._default_manager.get(user__id__exact=self.user_id)                                                                                              
        else:                                                                                                                                                                  
            return PremiumProfile._default_manager.get(user__id__exact=self.user_id)                                                                                                         

Я использую BaseProfile для отображения user_id к определенному user_type. Я хотел использовать ProxyProfile в качестве прокси, который загружает user_type в зависимости от профилей для модификации, как показано ниже

Содержание моей формы.

class ProfileForm(ModelForm):                                                                                                                                                    
...                                                                                                                                                                                 
    class Meta:                                                                                                                                                                 
        model   = ProxyProfile                                                                                                                                                  
        exclude = ('user','user_type')   
...

ProfileForm предоставляется Django-профили, используя следующий код в URLS.PY:

urlpatterns += patterns('',                                                                                                                                                      
    url(r'^profiles/edit/', edit_profile,                                                                                                                                        
        {'form_class': ProfileForm},                                                                                                                                             
        name='profiles_edit_profile'),                                                                                                                                           
    (r'^profiles/',include('profiles.urls')),                                                                                                                                    
)

Я также установил в настройках .py:

AUTH_PROFILE_MODULE = 'main.ProxyProfile'

Во время регистрации пользователей все данные БД заполнены правильно (похоже, все в порядке). Я регистрирую, используя форму, переданную Django-регистрацию:

urlpatterns += patterns('',                                                                                                                                                      
    url(r'^register/$', register,                                                                                                                                                
        {'form_class': UserRegistrationForm},                                                                                                                                    
        name='registration.views.register'),                                                                                                                                     
    (r'', include('registration.urls')),                                                                                                                                         
) 

из формы.

class UserRegistrationForm(RegistrationFormUniqueEmail, RegistrationFormTermsOfService):                                                                                         
    utype        = forms.ChoiceField(choices=USER_CHOICES)                                                                                               

    def save(self, profile_callback=None):                                                                                                                                       
        new_user = RegistrationProfile.objects.create_inactive_user(username=self.cleaned_data['username'],
                                                                    password.self.cleaned_data['password1'],                                                                     
                                                                    email=self.cleaned_data['email'],                                                                            
                                                                    )                                                                                                            
        new_base_profile = BaseProfile(user=new_user, user_type=self.cleaned_data['utype'])                                                                                      
        if self.cleaned_data['utype'] == "D":                                                                                                                                    
            new_profile = DemoProfile(user=new_user)                                                                                                                             
        if self.cleaned_data['utype'] == "F":                                                                                                                                    
            new_profile = FreeProfile(user=new_user)                                                                                                                             
        if self.cleaned_data['utype'] == "P":                                                                                                                                    
            new_profile = PremiumProfile(user=new_user)                                                                                                                             
        new_profile.save()                                                                                                                                                       
        new_base_profile.save()                                                                                                                                                  
        return new_user                

И фаза регистрации работает нормально.

У меня проблема с профилем Редактирование / Детали страницы. Мои профили отфильтрованы в ProxyProfile модели и используются в качестве FormModel в профиле form, не отображаются (я не вижу, что конкретные поля профиля не отображаются на страницу HTML), может быть, есть какой-то другой путь (больше похожего на Django Way :)), чтобы сделать это и рендеринг профиля модели в зависимости от поля user_type, который связан с моделью пользователя).

Заранее спасибо :)

Это было полезно?

Решение

Хорошо, наконец, у меня была идея, как я могу сделать это :)

В моем моделях .py:

class BaseManager(models.Manager):                                                                                                                                               
    def get(self, **kwargs):                                                                                                                                                     
        self.u = kwargs['user__id__exact']                                                                                                                                       
        self.bt = BaseProfile.manager.get(user__id__exact=self.u)                                                                                                                
        if self.bt.user_type == 'F':                                                                                                                                             
            return FreeProfile.objects.get(pk=self.u)                                                                                                                            
        elif self.bt.user_type == 'I':                                                                                                                                           
            return PremiumProfile.objects.get(pk=self.u)                                                                                                                            
        else:                                                                                                                                                                    
            return None                                                                                                                                                          

class BaseProfile(models.Model):                                                                                                                                                 
    objects   = BaseManager()                                                                                                                                                    
    manager   = UserManager()                                                                                                                                                    
    user      = models.OneToOneField(User, primary_key=True)                                                                                                                     
    user_type = models.CharField(max_length=1, blank=True, choices=USER_TYPES)                                                                                                   

class FreeProfile(models.Model):                                                                                                                                                 
    user      = models.OneToOneField(User, primary_key=True)                                                                                                                     
    free      = models.CharField(max_length=10, blank=True) 
    ...

class PremiumProfile(models.Model):                                                                                                                                                 
    user      = models.OneToOneField(User, primary_key=True)                                                                                                                     
    premium    = models.CharField(max_length=10, blank=True) 
    ...

В Custom Manager - BaseManager I возвращает объект профиля по перезаписанию Meth () методом, используемым Get_Profile. Я должен использовать USERMANAGER по имени просто «менеджер», чтобы предотвратить рекурсивный звонок пользовательского менеджера при назначении Self.Bt

Хорошо, это наполовину пути к достижению того, что я хочу, теперь я могу просматривать разные профили, прикрепленные к пользователям, используя приложение Django-профили.

Далее я хочу использовать модификацию для подготовки формы редактирования для пользовательских профилей. Пользователи могут иметь разные профили, поэтому я применил волшебный трюк, представленный в этом фрагменте: http://djangosnippets.org/snippets/2081/

А теперь в моих формах. Пусть у меня есть:

class FreeForm(forms.ModelForm):                                                                                                                                                 
    class Meta:                                                                                                                                                                  
        model = FreeProfile                                                                                                                                                      


class PremiumForm(forms.ModelForm):                                                                                                                                                 
    class Meta:                                                                                                                                                                  
        model = PremiumProfile         

Далее простые модели моделей для каждого профиля собраны в профиле (

class ProfileForm(ModelForm):                                                                                                                                                    
    def __init__(self, *args, **kwargs):                                                                                                                                        
    self.user = kwargs['instance'].user                                                                                                                                     
    profile_kwargs = kwargs.copy()                                                                                                                                          
    profile_kwargs['instance'] = self.user                                                                                                                                  
    self.bt = BaseProfile.manager.get(user__id__exact=self.user.id)                                                                                                         
    if self.bt.user_type == 'F':                                                                                                                                            
        self.profile_fields = FreeForm(*args, **profile_kwargs)                                                                                                             
    elif self.bt.user_type == 'P':                                                                                                                                          
        self.profile_fields = PremiumForm(*args, **profile_kwargs)                                                                                                             
    super(ProfileForm, self).__init__(*args, **kwargs)                                                                                                                      
    self.fields.update(self.profile_fields.fields)                                                                                                                          
    self.initial.update(self.profile_fields.initial) 

    class Meta:                                                                                                                                                                                                                                                                                                      
        model = BaseProfile     

    def save(self):
        ...

В настройках .py:

AUTH_PROFILE_MODULE = 'main.BaseProfile'

И это работает как очарование, но я задаюсь вопросом, является ли это Django способ достижения поддержки нескольких различных профилей с использованием Django-профилей? Он беспокоит меня, что я должен использовать Get () еще несколько раз, прежде чем представлять детали профиля или формы редактирования.

Но через 4 дня борьба с Джанго, чтобы сделать это, наконец, я могу хорошо спать сегодня вечером :)

Ваше здоровье

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top