根据 content_type 和字段名称链接识别 Django 用户 table
Identify Django User table based on content_type and field name links
我正在编写一个用于管理订阅的应用程序,例如年度俱乐部会员资格。有不同的成员类别,这些类别可以有管理员指定的标准,这些标准可能与数据库中的任何 table 相关。唯一的要求是必须有一个 link 返回给 Django 用户 table.
因此我得到了这个模型(定义如下),其中:
- name 是方便用户使用的类别名称
- content_type是一个link到
django_content_type
table来识别
table 正在为此类别设置标准
- filter_condition是select相关用户成为用户的条件
(例如,如果
content_type
table 是用户,那么这可能是
就像 {"is_active":"true"}
一样简单
- user_link 是由
content_type
标识的 table 中的字段
这是用户 table 的外键
我想在管理员保存时检查 user_link
对用户 table 做了 link,我正在为此目的编写 def clean (self)
。
我不知道如何将我的 content_type
和 user_link
字段转换成一个对象,我可以用它来检查它是用户 table. 非常欢迎帮助!
这是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',)
不同的描述可以有不同的标准。
为了验证目的,我得到了下面的解决方案,它取代了 def clean
中的主要 else
子句。
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.")
)
我现在需要弄清楚如何实际使用这些信息并将两者连接到一个字段中,这样我就可以 link 一直到 User
table
我正在编写一个用于管理订阅的应用程序,例如年度俱乐部会员资格。有不同的成员类别,这些类别可以有管理员指定的标准,这些标准可能与数据库中的任何 table 相关。唯一的要求是必须有一个 link 返回给 Django 用户 table.
因此我得到了这个模型(定义如下),其中:
- name 是方便用户使用的类别名称
- content_type是一个link到
django_content_type
table来识别 table 正在为此类别设置标准 - filter_condition是select相关用户成为用户的条件
(例如,如果
content_type
table 是用户,那么这可能是 就像{"is_active":"true"}
一样简单
- user_link 是由
content_type
标识的 table 中的字段 这是用户 table 的外键
我想在管理员保存时检查 user_link
对用户 table 做了 link,我正在为此目的编写 def clean (self)
。
我不知道如何将我的 content_type
和 user_link
字段转换成一个对象,我可以用它来检查它是用户 table. 非常欢迎帮助!
这是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',)
不同的描述可以有不同的标准。
为了验证目的,我得到了下面的解决方案,它取代了 def clean
中的主要 else
子句。
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.")
)
我现在需要弄清楚如何实际使用这些信息并将两者连接到一个字段中,这样我就可以 link 一直到 User
table