根据content_type和字段名称链接识别Django用户表

时间:2016-08-09 17:30:57

标签: python django django-contenttypes

我正在编写一个用于管理订阅的应用程序,例如年度俱乐部会员资格。有不同的成员资格,这些类别可以有管理员指定的标准,可以与数据库中的任何表相关。唯一的要求是必须有一个返回Django User表的链接。

因此我得到了这个模型(定义如下):

  • 名称是用户便利的类别名称
  • content_type 是指向要识别的django_content_type表的链接 表格正在为此类别设置标准
  • filter_condition 是用户选择相关用户的条件 (例如,如果content_type表是User,那么这可能是 就像{"is_active":"true"}
  • 一样简单
  • user_link 是由content_type标识的表格中的字段 这是User表的外键

我想在管理员保存时检查user_link指向User表的链接,并且我正在为此目的编写def clean (self)

我无法弄清楚如何将我的content_typeuser_link字段转换为我可以用来检查它是User表的对象。非常欢迎帮助!

这是models.py

from django.db import models
from django.contrib.auth.models import User
from django.conf import settings
import datetime

from django.core.exceptions import ValidationError
from django.utils.translation import ugettext_lazy as _

from django.contrib.contenttypes.models import ContentType
from subscriptions.fields import JSONField

class Category(models.Model):
    name = models.CharField('Category', max_length=30)
    content_type = models.ForeignKey(ContentType)
    filter_condition = JSONField(default="{}", help_text=_(u"Django ORM compatible lookup kwargs which are used to get the list of objects."))
    user_link = models.CharField(_(u"Link to User table"), max_length=64, help_text=_(u"Name of the model field which links to the User table.  'No-link' means this is the User table."), default="No-link")

    def clean (self):
        if self.user_link == "No-link":
            if self.content_type.app_label == "auth" and self.content_type.model == "user":
                pass
            else:
                raise ValidationError(
                    _("Must specify the field that links to the user table.")
                    )
        else:
            t = getattr(self.content_type, self.user_link)
            ct = ContentType.objects.get_for_model(t)
            if not ct.model == "user":
                raise ValidationError(
                    _("Must specify the field that links to the user table.")
                    )    



    def __unicode__(self):
        return self.name

    def _get_filter(self):
        # simplejson likes to put unicode objects as dictionary keys
        # but keyword arguments must be str type
        fc = {}
        for k,v in self.filter_condition.iteritems():
            fc.update({str(k): v})
        return fc

    def object_list(self):
        return self.content_type.model_class()._default_manager.filter(**self._get_filter())

    def object_count(self):
        return self.object_list().count()

    class Meta:
        verbose_name = _("Category")
        verbose_name_plural = _("Categories")
        ordering = ('name',)

不同的描述可以有不同的标准。

1 个答案:

答案 0 :(得分:1)

出于验证目的,我已经获得了以下解决方案,该解决方案取代了def clean中的主要 else: s = apps.get_model(self.content_type.app_label, self.content_type.model) if not hasattr(s, self.user_link): raise ValidationError( _("Must specify the field that links to the user table.") ) 条款。

User

我现在需要弄清楚如何实际使用这些信息并将两者连接到一个字段中,以便我可以链接到class CustomSimpleSearchBackend(haystack.backends.SimpleSearchBackend): def search(self, query_string, **kwargs): ... if query_string: for model in models: ... if 'users' in kwargs: qs = qs.filter(users=kwargs['users']) ... class CustomSimpleEngine(haystack.backends.BaseEngine): backend = CustomSimpleSearchBackend query = haystack.backends.simple_backend.SimpleSearchQuery