Django run cmd application

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) 

Trying to get my django web application to execute a python command line application with arguments. Not sure if this is the best way around this? If his advice would not be great. An attempt to enter user data through a web form and use it as arguments to execute the cmd application.

Help will be fantastic

Thanks William

+6
source share
3 answers

This seems like a good way if you want to execute a command in every save() your objects.

However, you must misinform your inputs: if users specify some special characters (for example && rm -rf /* ; or & ), it can violate your command, and this can be dangerous for your system (for example, < && rm -rf /* in an octet be interesting here: p). You should look at this answer that Popen uses to protect parameters:

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

I also correct the function declaration to get an instance as per the documentation .

Other: your __unicode__ function is incorrect, you cannot return 3 values ​​like this.

 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) 
+4
source

Why this code does not work is explained in another answer, I just answer his questions when the next time something like this happens.

I would like to advise how to debug, why this does not work.

 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 on the console launch server. With it, you can step-by-step do your code and execute ordinary Python commands (for example, printing).

Read the commands for inside the debugger here. Some IDEs come with Python debugging support and present it with a good graphical interface.

For repeated use: use oneliner:

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

And to make sure the strings are passed from the django webpage to the arguments in the cmd application.

You can:

translate them into lines to make sure

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

or use a line formatter (which is better than using the + sign and ensures that the input will be passed to the lines)

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

Read the string.format method here

+3
source
  • I would like to advise how to debug, why this does not work.

You can use the python / django logging mechanism and, if necessary, pass logging information. Shortly speaking:

 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) 

displays a warning to the console. If you use the django debug toolbar (recommended!) , You can easily log in using .debug-level (not.warning) and see the results on the web page.

You can enable these logs at every scheduled step in your workflow and see if everything is as it should be.

I am doing something like this (compiling the c code that is provided by the user) using the following snipplet code:

  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) 

(please ignore German words, they are not important for understanding the logic)

Another important thing is to use the correct encoding for all strings.

+2
source

Source: https://habr.com/ru/post/953786/


All Articles