Skip to main content
 首页 » 编程设计

python之根据 content_type 和字段名链接识别 Django User 表

2025年04月02日40over140

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

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

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

我想在管理员保存时检查 user_link 是否链接到用户表,为此我正在编写 def clean (self)。

我不知道如何将我的 content_type 和 user_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',) 

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

请您参考如下方法:

出于验证目的,我得到了下面的解决方案,它替换了 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.") 
                ) 

我现在需要弄清楚如何实际使用这些信息并将两者连接到一个字段中,这样我就可以链接到 User 表