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

标签 django django-admin django-authentication

我有一个 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 发表评论之后。

    我创建了 OfflineUser正如 GenericRelation 所建议的那样,我的 Trip :

    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 %}
    

    所以它在一定程度上起作用,现在我有一种奇怪的感觉,我没有完全理解 Hedde 的回答......

    每次我想对参与者做一些事情(计算他们,列出他们等)时,我都需要做两次吗?

    最佳答案

    使用 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 }}
    

    有很多 stackoverflow 和 google 结果可以帮助您,例如

    Generic many-to-many relationships

    关于Django - 如何为注册站点用户和非站点用户提供模型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13429793/

    相关文章:

    python - 如何获得用户权限?

    css - Django 压缩器和部署

    python - 在Python中循环列表时如何避免覆盖SQL UPDATE语句?

    html - 如何访问 django-admin 页面并扩展它?

    python - Django 1.8 管理表单 : AttributeError XForm object has no attribute 'save_m2m'

    python - django-admin 中的站点配置

    python - 在 django admin 中公开多个数据库

    django - modelformset_factory的empty_form初始值

    django - 如何将 db_index=True 添加到 django auth_user 的电子邮件字段

    django - 如何正确扩展 django 用户模型