【问题标题】:Django - using django-registration app with signalsDjango - 使用带有信号的 django-registration 应用程序
【发布时间】:2014-04-22 14:03:32
【问题描述】:

好的,所以我已经构建了一个基本的 Django 项目并成功安装了 django-registration 应用程序 - http://www.michelepasin.org/blog/2011/01/14/setting-up-django-registration/

我想扩展User 以包含生日、头像等信息。我创建了一个名为user_profile 的应用程序。这是注册应用程序中的signals.py

from django.dispatch import Signal
user_activated = Signal(providing_args=["user", "request"])

在我的新应用程序user_profile 中,侦听此信号的方法是什么?我想我应该创建一个signals.py 文件,但是我应该在里面写什么? from registration.signals import user_activated 声明还有什么?我创建的这个新应用还有一个 model.py,我想在激活新帐户时自动填充一些数据。

还有一个次要问题:当我将 URL 与基于类的视图链接时,会触发该类的哪个方法?如果我在基于类的视图中有 4 个方法,django 如何决定使用哪一个?谢谢

【问题讨论】:

  • 你到底想用这个信号做什么?将新用户添加到数据库时创建一个 UserProfile 对象?
  • 是的。 UserProfile 有一些字段,例如头像、性别、生日(这些字段不是必需的,也不会在初始化时完成),但是像 creation_time 和 update_time 这样的字段需要初始化。

标签: django django-registration django-signals


【解决方案1】:

好的,如果我理解你的问题,你会在 user_profile/models.py 文件的末尾添加这样的内容:

from django.contrib.auth.models import User
from django.db.models.signals import post_save

def create_user_profile(sender, instance, **kwargs):
    """ 
        Function to create user profile. 
        sender is the model class that sends the signal,
        while instance is an actual instance of that class
    """

    # your own logic here, for example :

    user = instance
    profile = UserProfile()
    profile.user = user  # link the profile to the user
    profile.save()

# connect the function to the signal, for User instances)
post_save.connect(create_user_profile, sender=User)

对于第二个问题,在基于类的视图执行期间调用了许多方法。为了使用基于类的视图,您的 URLconf 应该如下所示:

from myapp import views
from django.conf.urls import patterns, url

urlpatterns = patterns('',
    url(r'list_something', views.YourListView.as_view(), name="list_something"),
)

但是你不应该在你的视图中覆盖as_view() 方法。根据您要执行的操作,您将有其他方法可以覆盖。如果您提供更多信息,我也许可以帮助您。

【讨论】:

  • 是的,但是如果“YourListView”有 3 个方法 A、B 和 C 怎么办?哪一个被执行?
  • 大多数情况下,如果您使用基于类的通用视图,则不必在视图中编写自定义方法。请为此创建一个新问题,将您的视图代码复制粘贴到其中,并在此处提供链接,我会回答您。
  • 好的,我已经编辑了我的帖子。现在我的 models.py 的样子可以了吗?
  • 您错过了从我的 sn-p 导入的 post_save,并且您有一个错字:import datime 应该是 import datetime。除此之外,它似乎还可以。也许您应该考虑将related_name (see the docs) 属性添加到您的UserProfile.user 字段,以便能够从用户对象查询配置文件。
  • 总体情况是,我想为我正在尝试构建和使用的网站创建一个 /edit_profile 页面。并且会有像 first_name 和 last_name 这样的可修改字段,它们会影响 User 表,而 Gender、Birthday 等会影响 UserProfile 表。所以我连接了这两个表。而且我必须将表单组合在一起(它们只有 1 个提交按钮)
【解决方案2】:

感谢艾略特,这是我目前所拥有的:

signals.py 现已删除。

models.py:

    import datime

from django.db import models
from django.contrib.auth.models import User

try:
    from django.utils.timezone import now as datetime_now
except ImportError:
    datetime_now = datetime.datetime.now

class UserProfileManager(models.Manager):

    def create_user_profile(self, user):
        user_profile = self.create(user = user)
        return user_profile

class UserProfile(models.Model):

    YEARS = tuple(zip(range(1900, datetime_now.year)), zip(range(1900, datetime_now.year)))
    MONTHS = (
              ('January','January'),('February','February'),('March','March'),('April','April'),
              ('May','May'), ('June','June'),('July','July'),('August','August'),
              ('September','September'),('October','October'),('November','November'), ('December', 'December')

             )
    GENDERS = (('M', 'Male'), ('F', 'Female'))

    user = models.ForeignKey(User, unique=True, verbose_name=_('user'))
    birthday_year = models.CharField(max_length=1, blank = True,  null = True, choices=YEARS)
    birthday_month = models.CharField(max_length=1, blank = True,  null = True, choices=MONTHS)
    gender = models.CharField(max_length=1, blank = True,  null = True, choices=GENDERS)
    creation_time = models.DateTimeField(auto_now_add = True, auto_now = False)
    update_time = models.DateTimeField(auto_now_add = False, auto_now = True)

    class Meta:
            verbose_name = _('user profile')
            verbose_name_plural = _('user profiles')

    objects = UserProfileManager()

def create_user_profile(sender, instance, **kwargs):
    profile = UserProfile.objects.create_user_profile(user=instance)
    profile.save()

post_save.connect(create_user_profile, sender=User)

【讨论】:

  • 在您的信号中,您没有将 UserProfile 实例链接到 UserInstance。请尝试使用我提供的 sn-p(复制粘贴到你的 models.py 中)
猜你喜欢
  • 2011-06-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-04-14
  • 2012-02-21
  • 1970-01-01
  • 2013-09-18
  • 1970-01-01
相关资源
最近更新 更多