Django 1.7多站点用户模型 [英] Django 1.7 multisite User model

查看:115
本文介绍了Django 1.7多站点用户模型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想提供一个Django应用程序,它通过单个数据库为不同的用户集提供多个网站。想像一个博客应用程序,它将被不同主题的几个域使用,但是通过向模型添加一个站点字段来使用相同的数据库。

I want to serve a Django application that serves multiple web sites by single database but different user sets. Think like a blog application, it will be used by several domains with different themes, but use same database by adding a site field to models.

我使用 Django的SitesFramework 作为该作业。但是问题是,我不能为不同的站点分离用户模型。我想使用相同的用户模型,每个站点都有一个站点字段和电子邮件字段。

I use Django's SitesFramework for that job. But the problem is, I couldn't separate user models for different sites. I want to use same user model with a site field and email field that unique per site.

我试图扩展 AbstractUser 这样的模型:

I tried to extend AbstractUser model like that:

from django.contrib.auth.models import AbstractUser
from django.contrib.sites.models import Site
from django.contrib.sites.managers import CurrentSiteManager

class Member(AbstractUser):
    username = None
    site = models.ForeignKey(Site)

    USERNAME_FIELD = 'email'
    REQUIRED_FIELDS = []

    on_site = CurrentSiteManager()

    class Meta:
        unique_together = ('site', 'email')

但是出现这个错误:'Member.email'必须是唯一的,因为它被命名为'USERNAME_FIELD'。

该问题的最佳做法是什么?

What is the best practice for that issue?

推荐答案

我希望这种方法可以帮助你:

I hope this approach helps to you:

1)撰写用户保存前的名称:

1) Compose username before save:

from django.db import models
from django.contrib.auth.models import AbstractUser
from django.contrib.sites.models import Site
from django.contrib.sites.managers import CurrentSiteManager

class Member(AbstractUser):
    site = models.ForeignKey(Site)
    on_site = CurrentSiteManager()

    USERNAME_FIELD = 'username'
    REQUIRED_FIELDS = []

    class Meta:
        unique_together = ('site', 'email')

from django.db.models.signals import pre_save
from django.dispatch import receiver

@receiver(pre_save, sender=Member)
def compose_username(sender, instance, **kwargs):
    instance.username = "{0}__{1}".format( instance.email, instance.site_id ) 

2)然后覆盖 ModelBackend 在您的自定义auth后端:

2) Then overwrite ModelBackend in your custom auth backend:

from django.contrib.auth.backends import ModelBackend
from django.contrib.auth import get_user_model

class MyModelBackend(ModelBackend):

    def authenticate(self, username=None, password=None, **kwargs):
        UserModel = get_user_model()
        site = kwargs.get('site')
        identifier = "{0}__{1}".format( username, site )
        try:
            user = UserModel.objects.get(username=identifier)
            if user.check_password(password):
                return user
        except UserModel.DoesNotExist:
            # Run the default password hasher once to reduce the timing
            # difference between an existing and a non-existing user (#20760).
            UserModel().set_password(password)

3)记住在设置中设置自定义后端:

3) Remember set your custom backend on settings:

AUTH_USER_MODEL='s1.Member'
SITE_ID = 1
AUTHENTICATION_BACKENDS = ( 'MyApp.MyModule.MyModelBackend',)

4)验证时包括网站:

4) Include site when authenticate:

>>> from s1.models import Member as M
>>> m1 = M()
>>> m1.site_id = 1
>>> m1.email = 'peter@hello.com'
>>> m1.save()
>>> m1.set_password('hi')
>>> m1.save()
>>> 
>>> from django.contrib.auth import authenticate, login
>>> u=authenticate(username='peter@hello.com', password='hi', site=1)
>>> u
<Member: peter@hello.com_at_1>
>>> 

这篇关于Django 1.7多站点用户模型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆