Django - 如何为注册站点用户和非站点用户创建模型?

Posted

技术标签:

【中文标题】Django - 如何为注册站点用户和非站点用户创建模型?【英文标题】:Django - how to have models for registered site users and non-site users? 【发布时间】:2012-11-05 22:59:12 【问题描述】:

我有一个Trip 模型,它可以让许多参与者订阅给定的旅行和一个所有者。参与者是在网站上注册的用户,但我也希望能够将“离线”用户添加到旅行中,即在网站上没有帐户的用户,这样我就可以跟踪所有来的用户。 所有者和参与者都链接到 Userena 用户配置文件(附带问题:也许直接链接到 User 会更好?但是我怎样才能让 full_name 看到在内联管理员中的选择?)

class Trip(models.Model):
    name = models.CharField('trip name', max_length=200)
    type = models.ForeignKey(Category, related_name='categories')
    .
    .
    .
    slug = models.SlugField('trip slug', max_length=100)
    owner = models.ForeignKey(UserProfile, related_name='owner')
    participants = models.ManyToManyField(UserProfile, blank=True, null=True, related_name='participants')
    is_public = models.BooleanField("is visible?",db_index=True)

class ParticipationInline(admin.TabularInline):
    model = Trip.participants.through
    extra = 3

class TripAdmin(admin.ModelAdmin):

    def formfield_for_dbfield(self, db_field, **kwargs):
        if db_field.name in ('desc',):
            return db_field.formfield(widget=TinyMCE(
                attrs='cols': 100, 'rows': 20,
                mce_attrs='external_link_list_url': reverse('tinymce.views.flatpages_link_list'),
            ))
        return super(TripAdmin, self).formfield_for_dbfield(db_field, **kwargs)
    inlines = [
        ParticipationInline,
        ]
    exclude = ('participants',)
    prepopulated_fields = "slug": ("name",)
    list_display = ('name', 'type', 'date', 'dest','owner', 'is_public')
    list_filter = ['date', 'type']
    search_fields = ['name', 'dest', 'desc']
    date_hierarchy = 'date'

    class Media:
        js = ('js/tiny_mce/tiny_mce.js',
              'js/tiny_mce/textareas.js',)


admin.site.register(Trip, TripAdmin)

因此,当我通过管理界面添加Trip 时,我想首先从现有注册用户中选择一个参与者,如果在那里找不到他们,我希望能够内联添加一个新的“离线”参与者.实现这一目标的最佳方法是什么?

    有两个配置文件继承自我的UserProfile? 在Trip 中有一个单独的离线用户模型和两个多对多关系? 有更好的方法吗?

在 Hedde 发表评论后编辑

我按照我的Trip 的GenericRelation 的建议创建了OfflineUser

class OfflineUser(models.Model):
    first_name = models.CharField(_('first'), max_length=30)
    last_name = models.CharField(_('last'), max_length=30)
    ...
    content_type = models.ForeignKey(ContentType)
    object_id = models.PositiveIntegerField()
    content_object = generic.GenericForeignKey("content_type", "object_id")    

class Trip(models.Model):
    ...
    owner = models.ForeignKey(UserProfile, related_name='owner')
    participants = models.ManyToManyField(UserProfile, blank=True, null=True, related_name='participants')
    offline_users = generic.GenericRelation(OfflineUser)

添加OfflineUserInline 后,我可以将注册用户和离线用户添加到我的Trip! 然后我可以像这样列出这两种类型的Trip 参与者:

% if request.user.is_staff %
        <ul>
            % for participants in object.participants.all %
                <li>  participants.full_name 
                </li>
            % empty %
                No registered users!
            % endfor %
            % for participants in object.offline_users.all %
                <li>  participants.full_name 
                </li>
            % empty %
                No offline users!
            % endfor %
        </ul>
% endif %

所以它在某种程度上起作用了,现在我有一种奇怪的感觉,我没有完全理解赫德的答案......

每次我想对参与者做某事(数数、列出他们等)时,我都需要做两次吗?

【问题讨论】:

【参考方案1】:

使用contenttypes framework 可以使这更容易。您可以从管理员中过滤/隐藏内容类型,并在需要时清理表单或覆盖保存。对于“离线”参与者,我不会创建个人资料,而是模仿,例如:

class OfflineUser(models.Model):
    first_name = models.CharField(_('first name'), max_length=30)
    last_name = models.CharField(_('last name'), max_length=30)
    email = models.EmailField(_('e-mail address'))
    # field extensions
    ... = generic.GenericRelation(...)

    def get_profile(self):
        pass

    def get_full_name(self):
        """
        Add some default User methods so you can call them on
        the related_object without raising attribute errors
        """
        full_name = u'%s %s' % (self.first_name, self.last_name)
        return full_name.strip()

现在您可以执行以下操作:

 some_model.content_object.get_profile.get_full_name 

有很多 *** 和谷歌搜索结果可以帮助你,例如

Generic many-to-many relationships

【讨论】:

谢谢,在采纳您的建议后,我编辑了我的问题。请再看一遍,也许再给点提示......

以上是关于Django - 如何为注册站点用户和非站点用户创建模型?的主要内容,如果未能解决你的问题,请参考以下文章

如何为站点框架 django 设置多个 settings.py?

Django 如何构建依赖于站点的 URL?

如何为 django 驱动的 flash 站点的小型托管公司配置服务器?

如何为用户“伪装”或“重命名”页面名称/位置/ URL,但仍允许外部站点通过HTTP_REFERER正确读取真实的URL

Django 管理站点,更改不同用户的模型可见性

Django如何在类中注册用户