【问题标题】:Django model with only permissions defined breaks tests仅定义权限的 Django 模型中断测试
【发布时间】:2015-10-30 04:19:44
【问题描述】:

我在我的应用程序模型中使用元类来定义应用程序级别的权限,没有定义实际的字段。这按预期工作,但是当我尝试运行我的测试时,我得到 django.db.utils.OperationalError: no such table: xxx_xxx。有没有办法在运行单元测试时排除模型?

class feeds(models.Model):
    class Meta:
        permissions = (
            ("change_feed_defaults", "change_feed_defaults"),
            ("view_logs", "view_logs"),
            ("preview_tagger", "preview_tagger"),
            ("preview_url", "preview_url"),
            ("view_feeds", "view_feeds"),
            ("text_tag_feedback", "text_tag_feedback"),
        )

【问题讨论】:

    标签: python django unit-testing permissions models


    【解决方案1】:

    由于您没有提供完整的堆栈跟踪,我只能猜测发生了什么。

    django.db.utils.OperationalError: no such table: yourapp_yourmodel. 是常见的 您的数据库出现的错​​误并不能反映您的模型。

    如果您使用的是django>=1.7,也许您只是使用python manage.py makemigrations yourapp 创建相应的迁移文件。 您可能想阅读the documentation section that explains migrations。它是管理数据库状态(添加模型、字段等)的非常有用的工具,但有时很难全面了解。

    【讨论】:

    • 很高兴它有帮助 :) 如果它解决了您的问题,您可以考虑将我的答案标记为正确吗?
    【解决方案2】:

    我尝试了同样的事情.. 用一个假模型来持有额外的权限.. 我还有其他问题.. 和你的不一样.. 但是问题.. 所以我决定不顾一切地写一些代码来显式地创建我的额外权限,然后我将该代码放入我的库中:

    from django.contrib.contenttypes.models import ContentType
    from django.contrib.auth.models import Permission
    
    def get_or_create_permission(codename, name, content_type):
        permission = Permission.objects.filter(content_type=content_type, codename=codename).first()
    
        if not permission:
            permission =  Permission.objects.create(content_type=content_type, codename=codename, name=name)
            print "Created Permission: %s in content type: %s" % (permission, content_type,)
        else:
            print "Found Permission: %s in ContentType: %s" % (permission, content_type,)
    
        return permission
    
    def get_or_create_content_type(app_label, name, model):
          content_type = ContentType.objects.filter(app_label=app_label, model=model).first()
        if not content_type:
            content_type = ContentType.objects.create(app_label=app_label, model=model, name=name)
            print "Created ContentType: %s" % content_type
        else:
            print "Found ContentType: %s" % content_type
    
        return content_type
    

    现在在你的 urls.py 中(或其他任何将在启动时执行的地方):

    content_type = get_or_create_content_type('appname', 'Feeds', 'feeds')
    get_or_create_permission('change_feed_defaults', 'Change Feed Defaults', content_type)
    get_or_create_permission('view_logs', 'View Logs', content_type)
    # etc
    

    这可确保您的权限在启动时就在那里。这些天我会为此做一个包装器,这样我只需要传递一个权限字典,它就会在一个函数调用中完成所有事情......

    【讨论】:

      猜你喜欢
      • 2017-05-27
      • 2013-09-09
      • 1970-01-01
      • 2016-07-31
      • 2020-07-19
      • 1970-01-01
      • 1970-01-01
      • 2019-09-15
      • 1970-01-01
      相关资源
      最近更新 更多