代码之家  ›  专栏  ›  技术社区  ›  frequent

何时何地在Django中创建可配置的自定义组而不在启动时运行“no-such-table:auth\u group”?

  •  0
  • frequent  · 技术社区  · 6 年前

    ; Custom groups and permission settings
    [platform_group_list]
    TEAM = policy_team
    LEAD = policy_team_lead
    
    [platform_group_value_list]
    TEAM = Policy Team Member
    LEAD = Policy Team Lead
    

    我在里面分析 settings.py :

    PLATFORM_GROUP_LIST = raw_parser.items("platform_group_list")
    PLATFORM_GROUP_VALUE_LIST = raw_parser._sections["platform_group_value_list"]
    

    admin.py 因为这是群体“归属”的地方。所以我有:

    # admin.py (removed custom permissions, not relevant atm)
    from django.contrib import admin
    from django.contrib.auth.admin import UserAdmin as BaseUserAdmin
    from django.contrib.contenttypes.models import ContentType
    from django.contrib.auth.models import Group, Permission, User
    from django.contrib.auth import models as auth_models
    from django.core.exceptions import ObjectDoesNotExist
    from django.conf import settings
    from django.utils.translation import ugettext as _
    
    from account.models import SignupCodeResult
    from .models import UserConfig
    
    # BACKCOMPAT
    # add staff to the backcompat groups and vice versa, then remove the 
    # backcompat groups again. Used to be in migrations, fails when setting up
    # where custom permissions don't exist. Switch to configurable groups
    
    def create_group(name):
      return Group.objects.get_or_create(name=name)
    
    def delete_group(name):
      try:
        Group.objects.get(name=name).delete()
      except ObjectDoesNotExist:
        # pass
        raise Exception("admin: trying to delete non-existing group")
    
    def get_permission(app, name):
      try:
        return Permission.objects.get(content_type__app_label=app, codename=name)
      except:
        return False
    
    def backcompat_init_teams_and_permissions():
      for group_title in settings.BACKCOMPAT_GROUP_LIST:
        new_group, created = create_group(group_title)
    
        if created:
          for user in User.objects.filter(is_staff=True, is_active=True):
            user.groups.add(new_group)
    
          for permission_name in settings.BACKCOMPAT_PERMISSION_LIST:
            new_permission = get_permission("initproc", permission_name)
            if new_permission:
              new_group.permissions.add(new_permission)
    
    def backcompat_reverse_teams_and_permissions():
      for group_title in settings.BACKCOMPAT_GROUP_LIST:
        for user in User.objects.filter(groups__name=group_title, is_active=True):
          user.is_staff = True
          user.save()
      delete_group(group_title)
    
    # new and dynamic
    def create_custom_groups_and_permissions():
      for (group_key, group_title) in settings.PLATFORM_GROUP_LIST:
        new_group, created = create_group(settings.PLATFORM_GROUP_VALUE_LIST[group_key])
        if created:
          new_group.save()
    
    class UserConfigInline(admin.StackedInline):
      model = UserConfig
      can_delete = False
      verbose_name_plural = 'config'
    
    # Define a new User admin
    class UserAdmin(BaseUserAdmin):
      inlines = (UserConfigInline, )
    
    # Re-register UserAdmin
    admin.site.unregister(User)
    admin.site.register(User, UserAdmin)
    admin.site.register(SignupCodeResult)
    admin.site.register(Permission)
    
    # XXX where to call all of these?
    
    # backcompat - move existing staff to custom group and custom group to staff
    backcompat_init_teams_and_permissions()
    backcompat_reverse_teams_and_permissions()
    
    # define custom groups as per init.ini
    create_custom_groups_and_permissions()
    

    当应用程序启动并运行时,它可以正常工作,但是当我从头开始设置它时,我不能调用它 runserver , makemigrations migrate 因为所有的都失败了

    return Group.objects.get_or_create(name=name)
    

    具有 django.db.utils.OperationalError: no such table: auth_group

    我想这意味着当我已经尝试访问它时,表没有被创建。

    我可以让我的应用程序的工作,通过评出上述呼吁加上另一个错误时,试图访问组中 forms.py 迁移 当我启动应用程序并再次取消注释时,组(和权限)被正确添加。所以对我来说这只是一个“鸡和蛋”的问题。

    问题:
    no such table: auth_group 在创建表之前访问它?我可以把所有东西移回迁移中,但我认为这不是一个合适/理想的地方。 似乎“太早了”,而且我没有找到类似于“所有数据库表都已设置”的信号。

    谢谢你的帮助!

    以下是错误跟踪:

    Traceback (most recent call last):
      File "/usr/local/demo/venv/lib/python3.6/site-packages/django/db/backends/utils.py", line 64, in execute
        return self.cursor.execute(sql, params)
      File "/usr/local/demo/venv/lib/python3.6/site-packages/django/db/backends/sqlite3/base.py", line 337, in execute
        return Database.Cursor.execute(self, query, params)
    sqlite3.OperationalError: no such table: auth_group
    
    The above exception was the direct cause of the following exception:
    
    Traceback (most recent call last):
      File "abstimmungstool/manage.py", line 22, in <module>
        execute_from_command_line(sys.argv)
      File "/usr/local/demo/venv/lib/python3.6/site-packages/django/core/management/__init__.py", line 367, in execute_from_command_line
        utility.execute()
      File "/usr/local/demo/venv/lib/python3.6/site-packages/django/core/management/__init__.py", line 359, in execute
        self.fetch_command(subcommand).run_from_argv(self.argv)
      File "/usr/local/demo/venv/lib/python3.6/site-packages/django/core/management/base.py", line 294, in run_from_argv
        self.execute(*args, **cmd_options)
      File "/usr/local/demo/venv/lib/python3.6/site-packages/django/core/management/base.py", line 342, in execute
        self.check()
      File "/usr/local/demo/venv/lib/python3.6/site-packages/django/core/management/base.py", line 374, in check
        include_deployment_checks=include_deployment_checks,
      File "/usr/local/demo/venv/lib/python3.6/site-packages/django/core/management/base.py", line 361, in _run_checks
        return checks.run_checks(**kwargs)
      File "/usr/local/demo/venv/lib/python3.6/site-packages/django/core/checks/registry.py", line 81, in run_checks
        new_errors = check(app_configs=app_configs)
      File "/usr/local/demo/venv/lib/python3.6/site-packages/django/core/checks/urls.py", line 14, in check_url_config
        return check_resolver(resolver)
      File "/usr/local/demo/venv/lib/python3.6/site-packages/django/core/checks/urls.py", line 24, in check_resolver
        for pattern in resolver.url_patterns:
      File "/usr/local/demo/venv/lib/python3.6/site-packages/django/utils/functional.py", line 35, in __get__
        res = instance.__dict__[self.name] = self.func(instance)
      File "/usr/local/demo/venv/lib/python3.6/site-packages/django/urls/resolvers.py", line 313, in url_patterns
        patterns = getattr(self.urlconf_module, "urlpatterns", self.urlconf_module)
      File "/usr/local/demo/venv/lib/python3.6/site-packages/django/utils/functional.py", line 35, in __get__
        res = instance.__dict__[self.name] = self.func(instance)
      File "/usr/local/demo/venv/lib/python3.6/site-packages/django/urls/resolvers.py", line 306, in urlconf_module
        return import_module(self.urlconf_name)
      File "/usr/local/demo/venv/lib/python3.6/importlib/__init__.py", line 126, in import_module
        return _bootstrap._gcd_import(name[level:], package, level)
      File "<frozen importlib._bootstrap>", line 994, in _gcd_import
      File "<frozen importlib._bootstrap>", line 971, in _find_and_load
      File "<frozen importlib._bootstrap>", line 955, in _find_and_load_unlocked
      File "<frozen importlib._bootstrap>", line 665, in _load_unlocked
      File "<frozen importlib._bootstrap_external>", line 678, in exec_module
      File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
      File "/usr/local/demo/abstimmungstool/voty/urls.py", line 38, in <module>
        ) + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
      File "/usr/local/demo/venv/lib/python3.6/site-packages/django/conf/urls/__init__.py", line 50, in include
        urlconf_module = import_module(urlconf_module)
      File "/usr/local/demo/venv/lib/python3.6/importlib/__init__.py", line 126, in import_module
        return _bootstrap._gcd_import(name[level:], package, level)
      File "<frozen importlib._bootstrap>", line 994, in _gcd_import
      File "<frozen importlib._bootstrap>", line 971, in _find_and_load
      File "<frozen importlib._bootstrap>", line 955, in _find_and_load_unlocked
      File "<frozen importlib._bootstrap>", line 665, in _load_unlocked
      File "<frozen importlib._bootstrap_external>", line 678, in exec_module
      File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
      File "/usr/local/demo/abstimmungstool/voty/initadmin/urls.py", line 13, in <module>
        from . import views
      File "/usr/local/demo/abstimmungstool/voty/initadmin/views.py", line 33, in <module>
        from .forms import (UploadFileForm, LoginEmailOrUsernameForm, UserEditForm,
      File "/usr/local/demo/abstimmungstool/voty/initadmin/forms.py", line 93, in <module>
        class UserModerateForm(forms.ModelForm):
      File "/usr/local/demo/abstimmungstool/voty/initadmin/forms.py", line 140, in UserModerateForm
        widget=forms.CheckboxSelectMultiple,choices=[(x.id, x.name) for x in Group.objects.all()],
      File "/usr/local/demo/venv/lib/python3.6/site-packages/django/db/models/query.py", line 256, in __iter__
        self._fetch_all()
      File "/usr/local/demo/venv/lib/python3.6/site-packages/django/db/models/query.py", line 1087, in _fetch_all
        self._result_cache = list(self.iterator())
      File "/usr/local/demo/venv/lib/python3.6/site-packages/django/db/models/query.py", line 54, in __iter__
        results = compiler.execute_sql()
      File "/usr/local/demo/venv/lib/python3.6/site-packages/django/db/models/sql/compiler.py", line 835, in execute_sql
        cursor.execute(sql, params)
      File "/usr/local/demo/venv/lib/python3.6/site-packages/django/db/backends/utils.py", line 79, in execute
        return super(CursorDebugWrapper, self).execute(sql, params)
      File "/usr/local/demo/venv/lib/python3.6/site-packages/django/db/backends/utils.py", line 64, in execute
        return self.cursor.execute(sql, params)
      File "/usr/local/demo/venv/lib/python3.6/site-packages/django/db/utils.py", line 94, in __exit__
        six.reraise(dj_exc_type, dj_exc_value, traceback)
      File "/usr/local/demo/venv/lib/python3.6/site-packages/django/utils/six.py", line 685, in reraise
        raise value.with_traceback(tb)
      File "/usr/local/demo/venv/lib/python3.6/site-packages/django/db/backends/utils.py", line 64, in execute
        return self.cursor.execute(sql, params)
      File "/usr/local/demo/venv/lib/python3.6/site-packages/django/db/backends/sqlite3/base.py", line 337, in execute
        return Database.Cursor.execute(self, query, params)
    django.db.utils.OperationalError: no such table: auth_group
    
    1 回复  |  直到 6 年前
        1
  •  0
  •   frequent    6 年前

    经过一些研究,我发现定制管理命令最适合 blog , docs set_groups_and_permissions 像这样的命令:

    # -*- coding: utf-8 -*-
    from django.core.management import BaseCommand
    from django.contrib.contenttypes.models import ContentType
    from django.contrib.auth.models import Group, Permission, User
    from django.contrib.auth import models as auth_models
    from django.core.exceptions import ObjectDoesNotExist
    from django.conf import settings
    from django.utils.translation import ugettext as _
    
    # BACKCOMPAT
    # add all staff to the defined backcompat role and vice versa, then remove the 
    # backcompat groups again. Used to be in migrations, fails when setting up
    # where custom permissions don't exist. Plus, custom groups should be
    # configurable, so we replicate what was done here, then switch to configurable
    # custom groups and permissions
    def create_group(name):
    
      # returns group, created (True/False)
      return Group.objects.get_or_create(name=name)
    
    def delete_group(name):
      try:
        Group.objects.get(name=name).delete()
      except ObjectDoesNotExist:
        # pass
        raise Exception("initadmin: trying to delete non-existing group")
    
    def get_permission(app, name):
      try:
        return Permission.objects.get(content_type__app_label=app, codename=name)
      except:
        return False
    
    def backcompat_init_teams_and_permissions():
      for group_title in settings.BACKCOMPAT_ROLE_LIST:
        new_group, created = create_group(group_title)
    
        if created:
          for user in User.objects.filter(is_staff=True, is_active=True):
            user.groups.add(new_group)
    
          for permission_name in settings.BACKCOMPAT_PERMISSION_LIST:
            new_permission = get_permission("initproc", permission_name)
            if new_permission:
              new_group.permissions.add(new_permission)
    
    def backcompat_reverse_teams_and_permissions():
      for group_title in settings.BACKCOMPAT_ROLE_LIST:
        for user in User.objects.filter(groups__name=group_title, is_active=True):
          user.is_staff = True
          user.save()
      delete_group(group_title)
    
    def create_custom_groups_and_permissions():
      for (group_key, group_title) in settings.PLATFORM_GROUP_LIST:
        new_group, created = create_group(settings.PLATFORM_GROUP_VALUE_LIST[group_key])
        if created:
          new_group.save()
    
    # ---------------------------------- Command -----------------------------------
    class Command(BaseCommand):
      help = "Create groups, permissions as defined in settings.py"
    
      def handle(self, *args, **options):
    
        backcompat_init_teams_and_permissions()
        backcompat_reverse_teams_and_permissions()
        create_custom_groups_and_permissions()
    
        print("Groups, Permissions created.")
    

    关于我的另一个错误 forms.py Groups.objects.all 并在运行时填充它。

    class UserGiveGroupPrivilegeForm(forms.ModelForm):
    
      class Meta:
        model = get_user_model()
        fields = ["groups"]
    
      def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        for field in iter(self.fields):
          self.fields[field].widget.attrs.update({
            'class': 'form-control'
          })
    
      groups = forms.MultipleChoiceField(
        #widget=forms.CheckboxSelectMultiple,choices=[(x.id, x.name) for x in Group.objects.all()],
        widget=forms.CheckboxSelectMultiple,
        required=False,
        label=_("Groups"),
        help_text=_("Please select the group(s) this user should belong to.")
      )
      action = forms.CharField(
        max_length=24,
        widget=forms.HiddenInput(),
        initial="give_group_privileges"
      )
    

    不是最佳的,但还可以。

    有了以上我可以从头开始安装我的应用程序没有任何错误 django.db.utils.OperationalError: no such table: auth_group 从对表的调用开始。