6
from django.db import models
import os
from django.db.models.signals import post_save
import sys

class Form(models.Model):
    site = models.CharField(max_length=50)
    num = models.CharField(max_length=10)
    octet = models.CharField(max_length=30)

    def __unicode__(self):
        return self.site
        return self.num
        return self.octet

def create_conf(sender, **kwargs):
    os.system("/usr/local/build " + self.site + ' ' + self.num + ' ' + self.octet)

post_save.connect(create_conf, sender=Form)

试图让我的 django web 应用程序使用参数执行 python 命令行应用程序。不确定这是否是最好的解决方法?如果它没有任何建议会很棒。尝试通过 Web 表单从用户那里获取输入并将其用作执行 cmd 应用程序的参数。

帮助会很棒

谢谢威廉

4

3 回答 3

4

save()如果您想在每个对象上执行命令,这似乎是一个好方法。

但是,您应该清理您的输入:如果用户设置了一些特殊字符(例如,;&),它可能会破坏您的命令,并且可能对您的系统造成风险(例如&& rm -rf /*,八位字节中的一个在这里可能很有趣:p)。您应该查看用于保护参数的这个答案Popen

from subprocess import Popen  

def create_conf(sender, instance, **kwargs):
     p1 = Popen(["/usr/local/build", instance.site, instance.num, instance.octet])

根据文档,我还修复了函数声明以获取实例。

另一件事:你的__unicode__函数不正确,你不能像这样返回 3 个值。

class Form(models.Model):
    site = models.CharField(max_length=50)
    num = models.CharField(max_length=10)
    octet = models.CharField(max_length=30)

    def __unicode__(self):
        return "%s %s %s" % (self.site, self.num, self.octet)
于 2013-09-16T07:47:25.967 回答
3

Why this code doesn't work is explained in another answer, I'm just answering his questions for the next time something like this happens.

Would like advice on how to debug why this is not working.

def create_conf(sender, **kwargs):
    import pdb
    pdb.set_trace()
    os.system("/usr/local/build " + self.site + ' ' + self.num + ' ' + self.octet)

This will give you the built-in Python debugger, in the console runserver is running. With it, you can go trough your code step by step, and execute regular Python commands (like print).

Read up on the commands for inside the debugger here Some IDEs come with Python debugging support, and present it with a nice GUI.

When using it a lot: use the oneliner:

import pdb; pdb.set_trace;  # yes, Python supports semicolons 
                            # (although its not recommended)

And to make sure that the strings are being passed through from django web page to arguments on cmd application.

You can either:

cast them to strings to make sure

os.system("/usr/local/build " + str(self.site) + ' ' + str(self.num) + ' ' + str(self.octet))

or use the string formatter (which is better than using the + sign and makes sure input gets cast to strings)

os.system("usr/local/build {0} {1} {2}".format(self.site, self.num, self.octet))

Read up on the string .format method here

于 2013-09-20T21:33:51.847 回答
2
  1. 想知道如何调试为什么这不起作用的建议。

您可以使用python / django 日志机制,并在需要的地方抛出日志信息。简而言之:

import logging
logger = logging.getLogger(__name__) # Get an instance of a logger
my_custom_command = "/usr/local/build " + self.site + ' ' + self.num + ' ' + self.octet
logger.warning(my_custom_command)

向控制台打印警告消息。如果您使用django 调试工具栏(强烈推荐!),您可以使用 .debug 级别(不是 .warning)轻松登录并在网页上查看结果。

您可以在工作流程的每个预期步骤中包含这些日志记录消息,并检查一切是否正常。

我正在使用以下代码片段做这样的事情(编译用户提供的 c 代码):

    try:
        cfile = os.path.join(MEDIA_ROOT, 'temp/src/cfile.c')
        ofile = os.path.join(MEDIA_ROOT, 'temp/src/cfile.o')
        efile = os.path.join(MEDIA_ROOT, 'temp/src/cfile.exe')
        command_string = 'gcc -O0 -g3 -Wall -c -fmessage-length=0 ' + cfile + ' -o ' + ofile
        compile_result = subprocess.check_output(command_string,stderr=subprocess.STDOUT,shell=True)
        if compile_result != "": #Compile error
            self.ausgabe = "Compile:\n"
            self.ausgabe += str(compile_result)
    except:
        self.ausgabe = u"Compilierfehler:\n"
        self.ausgabe += str(compile_result)

(请忽略德语单词,它们对于理解逻辑并不重要)

可能重要的另一件事是对所有字符串使用正确的编码。

于 2013-09-19T18:50:54.567 回答