运行由django app

时间:2018-01-25 04:08:30

标签: django python-3.x path scripting frameworks

我正在为我的需求构建一个完全开源的testrunner,但我遇到了一些问题。测试运行器为各种路径中的一组脚本解析yaml文件并执行脚本并使用我将创建的lib来返回结果。现在我有一个简单的ping脚本,我正在努力运行和测试,因为我进步但我收到了很多错误。错误如下,所有源代码也显示在错误下方。

这里的github回购就在这里。随意拉进来测试我看到的问题。 https://github.com/castaway2000/testrunner

问题:

我正在尝试使用我构建的testrunner来解析yaml文件,以获取我正在为我正在使用的项目编写的脚本的路径。

例如,如果想在目标上使用一组特定测试,我可以为每组测试类型创建一个yaml文件。

我遇到了一个问题然而,文件的相对路径和确切路径无法使用django库,导致它无法找到库的路径,除非它从顶层运行django应用程序(即./ping_google.py vs ./testcases/ping_google.py)

但最重要的是,当独立库引用models.py并且admin.py无法从同一目录导入模型时,django应用程序说没有运行。我需要帮助修复和理解这个问题。

这是rundown(stacktrace):

Enterprize:testrunner xwing$ python3 ping_google.py
Traceback (most recent call last):
  File "ping_google.py", line 1, in <module>
    from testrunnerlib.test import HostInterface
  File "/Users/xwing/PycharmProjects/testrunner/testrunnerlib/test.py", line 11, in <module>
    from testrunner.models import Host, TestSuite
  File "/Users/xwing/PycharmProjects/testrunner/testrunner/models.py", line 5, in <module>
    class Host(models.Model):
  File "/usr/local/lib/python3.6/site-packages/django/db/models/base.py", line 105, in __new__
    app_config = apps.get_containing_app_config(module)
  File "/usr/local/lib/python3.6/site-packages/django/apps/registry.py", line 237, in get_containing_app_config
    self.check_apps_ready()
  File "/usr/local/lib/python3.6/site-packages/django/apps/registry.py", line 124, in check_apps_ready
    raise AppRegistryNotReady("Apps aren't loaded yet.")
django.core.exceptions.AppRegistryNotReady: Apps aren't loaded yet.

我在django设置文件中放入导入django和django.setup()之后,上面的错误就消失了但是我收到以下错误:

Enterprize:testrunner xwing$ python3 ping_google.py
Traceback (most recent call last):
  File "ping_google.py", line 1, in <module>
    from testrunnerlib.test import HostInterface
  File "/Users/xwing/PycharmProjects/testrunner/testrunnerlib/test.py", line 11, in <module>
    from testrunner.models import Host, TestSuite
  File "/Users/xwing/PycharmProjects/testrunner/testrunner/models.py", line 5, in <module>
    class Host(models.Model):
  File "/Users/xwing/PycharmProjects/testrunner/testrunner/models.py", line 6, in Host
    ip_address = models.CharField(max_length=16)
  File "/usr/local/lib/python3.6/site-packages/django/db/models/fields/__init__.py", line 1043, in __init__
    super(CharField, self).__init__(*args, **kwargs)
  File "/usr/local/lib/python3.6/site-packages/django/db/models/fields/__init__.py", line 166, in __init__
    self.db_tablespace = db_tablespace or settings.DEFAULT_INDEX_TABLESPACE
  File "/usr/local/lib/python3.6/site-packages/django/conf/__init__.py", line 53, in __getattr__
    self._setup(name)
  File "/usr/local/lib/python3.6/site-packages/django/conf/__init__.py", line 41, in _setup
    self._wrapped = Settings(settings_module)
  File "/usr/local/lib/python3.6/site-packages/django/conf/__init__.py", line 97, in __init__
    mod = importlib.import_module(self.SETTINGS_MODULE)
  File "/usr/local/Cellar/python3/3.6.1/Frameworks/Python.framework/Versions/3.6/lib/python3.6/importlib/__init__.py", line 126, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "/Users/xwing/PycharmProjects/testrunner/testrunner/settings.py", line 133, in <module>
    django.setup()
  File "/usr/local/lib/python3.6/site-packages/django/__init__.py", line 27, in setup
    apps.populate(settings.INSTALLED_APPS)
  File "/usr/local/lib/python3.6/site-packages/django/apps/registry.py", line 115, in populate
    app_config.ready()
  File "/usr/local/lib/python3.6/site-packages/django/contrib/admin/apps.py", line 23, in ready
    self.module.autodiscover()
  File "/usr/local/lib/python3.6/site-packages/django/contrib/admin/__init__.py", line 26, in autodiscover
    autodiscover_modules('admin', register_to=site)
  File "/usr/local/lib/python3.6/site-packages/django/utils/module_loading.py", line 50, in autodiscover_modules
    import_module('%s.%s' % (app_config.name, module_to_search))
  File "/usr/local/Cellar/python3/3.6.1/Frameworks/Python.framework/Versions/3.6/lib/python3.6/importlib/__init__.py", line 126, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "/Users/xwing/PycharmProjects/testrunner/testrunner/admin.py", line 3, in <module>
    from testrunner.models import Host, TestSuite
ImportError: cannot import name 'Host'

修复此问题将有助于测试testrunner的其余构建场景,但我仍然需要有关python需要使用的相对路径和环境的建议,以了解在哪里查找这些库。如果可能的话,我可以将lib放在根python目录中,这样lib就与问题无关。

问题文件:

from testrunnerlib.test import HostInterface
from testrunnerlib.outcomes import Outcomes

from ping3 import ping


def pinger(host):
    result = Outcomes()
    try:
        ping_google = ping(host)
        print(ping_google)
        if ping_google:
            return result.passed()
        msg = 'ping had an issue, the following is all we know %s' % ping_google
        return result.failed(msg)
    except Exception as e:
        return result.aborted(exception=e)

if __name__ == '__main__':
    pinger(HostInterface().target)

只有django导入的lib:

import yaml
import subprocess

from testrunner.models import Host, TestSuite


class HostInterface(object):
    def __init__(self):
        self._target = 'not set'

    @property
    def target(self):
        return self._target

    @target.setter
    def target(self, value):
        print("setter of target called", value)
        self._target = value

    @target.deleter
    def target(self):
        print("deleter of target called")
        del self._target

    def host(self):
        out = Host.objects.get(id=self.target).name
        return out


class YamlInterface:
    def __init__(self, yamlfile):
        self.file = yamlfile

    def handle_yaml(self):
        data = TestSuite.objects.get(id=self.file)
        yamldata = yaml.safe_load(data.text)
        for i in yamldata['testsuite']:
            status = subprocess.call('python3 %s' % i, shell=True)
            print(status)


def run_tests(host, yaml):
    h_interface = HostInterface()
    h_interface.target = host
    h_interface.host()
    yaml = YamlInterface(yaml)
    yaml.handle_yaml()

模特:

from __future__ import unicode_literals
from django.db import models


class Host(models.Model):
    ip_address = models.CharField(max_length=16)
    port = models.IntegerField()
    name = models.CharField(max_length=256)


class TestSuite(models.Model):
    name = models.CharField(max_length=256)
    text = models.TextField()
    is_active = models.BooleanField(default=True)
    created = models.DateTimeField(auto_now_add=True, auto_now=False)
    updated = models.DateTimeField(auto_now_add=False, auto_now=True)

    def __str__(self):
        return "%s" % self.name

admin.py

from django.contrib import admin
from django import forms
from testrunner.models import Host, TestSuite


class HostAdmin(admin.ModelAdmin):
    list_display = ['name']
    fields = ('name', 'ip_address', 'port')
    def __str__(self):
        return '%s' % self.name
    pass
admin.site.register(Host, HostAdmin)


class TestSuiteAdmin(admin.ModelAdmin):
    def formfield_for_dbfield(self, db_field, **kwargs):
        formfield = super(TestSuiteAdmin, self).formfield_for_dbfield(db_field, **kwargs)
        if db_field.name == 'text':
            formfield.widget = forms.Textarea(attrs=formfield.widget.attrs)
        return formfield
admin.site.register(TestSuite, TestSuiteAdmin)

1 个答案:

答案 0 :(得分:1)

您需要制作Django管理命令。这将允许您创建允许您使用Django所有功能的脚本。

您可以将此命令作为python3 manage.py ping_google

运行

要创建管理命令,

在你的apps文件夹中,创建一个名为management的模块(创建一个名为management的文件夹并在其中放置 init .py文件)

在管理文件夹中,创建一个命令模块(文件夹和 init .py文件)

在命令文件夹中创建ping_google.py文件。

命令是这样写的,

from django.core.management.base import BaseCommand, CommandError

class Command(BaseCommand):

    help = 'Desc of your command'

    def handle(self, *args, **options):
        #  Your logic goes here

您可以阅读有关自定义django命令here

的更多信息