Передайте начальное значение полю формы Django

Лично, я использовал бы C# в качестве языка сценариев. Платформа.NET (и Моно, Matthew Scharley спасибо) на самом деле включает компиляторы для каждого из языков.NET в самой платформе.

В основном, существует 2 части к реализации этой системы.

  1. Позволяют пользователю компилировать код, Это относительно легко, и может быть сделано только в нескольких строках кода (хотя Вы могли бы хотеть добавить ошибочное диалоговое окно, которое, вероятно, будет парой дюжины большего количества строк кода, в зависимости от того, как применимый Вы хотите, чтобы это было).

  2. Создают и используют классы, содержавшие в рамках скомпилированного блока, Это немного более трудно, чем предыдущий шаг (требует крошечного бита отражения). В основном необходимо просто рассматривать скомпилированный блок как "плагин" для программы. Существует довольно много учебных руководств на различных способах, которыми можно создать сменную систему в C# (Google является другом).

я реализовал "быстрое" приложение, чтобы продемонстрировать, как можно реализовать эту систему (включает 2 рабочих сценария!). Это - полный код для приложения, просто создайте новый и вставьте код в "program.cs" файле. В этой точке я должен принести извинения за большой блок кода, который я собираюсь вставить (я не предназначал, чтобы это было настолько большим, но увлеклось немного моим комментарием)


using System;
using System.Windows.Forms;
using System.Reflection;
using System.CodeDom.Compiler;

namespace ScriptingInterface
{
    public interface IScriptType1
    {
        string RunScript(int value);
    }
}

namespace ScriptingExample
{
    static class Program
    {
        /// 
        /// The main entry point for the application.
        /// 
        [STAThread]
        static void Main()
        {

            // Lets compile some code (I'm lazy, so I'll just hardcode it all, i'm sure you can work out how to read from a file/text box instead
            Assembly compiledScript = CompileCode(
                "namespace SimpleScripts" +
                "{" +
                "    public class MyScriptMul5 : ScriptingInterface.IScriptType1" +
                "    {" +
                "        public string RunScript(int value)" +
                "        {" +
                "            return this.ToString() + \" just ran! Result: \" + (value*5).ToString();" +
                "        }" +
                "    }" +
                "    public class MyScriptNegate : ScriptingInterface.IScriptType1" +
                "    {" +
                "        public string RunScript(int value)" +
                "        {" +
                "            return this.ToString() + \" just ran! Result: \" + (-value).ToString();" +
                "        }" +
                "    }" +
                "}");

            if (compiledScript != null)
            {
                RunScript(compiledScript);
            }
        }

        static Assembly CompileCode(string code)
        {
            // Create a code provider
            // This class implements the 'CodeDomProvider' class as its base. All of the current .Net languages (at least Microsoft ones)
            // come with thier own implemtation, thus you can allow the user to use the language of thier choice (though i recommend that
            // you don't allow the use of c++, which is too volatile for scripting use - memory leaks anyone?)
            Microsoft.CSharp.CSharpCodeProvider csProvider = new Microsoft.CSharp.CSharpCodeProvider();

            // Setup our options
            CompilerParameters options = new CompilerParameters();
            options.GenerateExecutable = false; // we want a Dll (or "Class Library" as its called in .Net)
            options.GenerateInMemory = true; // Saves us from deleting the Dll when we are done with it, though you could set this to false and save start-up time by next time by not having to re-compile
            // And set any others you want, there a quite a few, take some time to look through them all and decide which fit your application best!

            // Add any references you want the users to be able to access, be warned that giving them access to some classes can allow
            // harmful code to be written and executed. I recommend that you write your own Class library that is the only reference it allows
            // thus they can only do the things you want them to.
            // (though things like "System.Xml.dll" can be useful, just need to provide a way users can read a file to pass in to it)
            // Just to avoid bloatin this example to much, we will just add THIS program to its references, that way we don't need another
            // project to store the interfaces that both this class and the other uses. Just remember, this will expose ALL public classes to
            // the "script"
            options.ReferencedAssemblies.Add(Assembly.GetExecutingAssembly().Location);

            // Compile our code
            CompilerResults result;
            result = csProvider.CompileAssemblyFromSource(options, code);

            if (result.Errors.HasErrors)
            {
                // TODO: report back to the user that the script has errored
                return null;
            }

            if (result.Errors.HasWarnings)
            {
                // TODO: tell the user about the warnings, might want to prompt them if they want to continue
                // runnning the "script"
            }

            return result.CompiledAssembly;
        }

        static void RunScript(Assembly script)
        {
            // Now that we have a compiled script, lets run them
            foreach (Type type in script.GetExportedTypes())
            {
                foreach (Type iface in type.GetInterfaces())
                {
                    if (iface == typeof(ScriptingInterface.IScriptType1))
                    {
                        // yay, we found a script interface, lets create it and run it!

                        // Get the constructor for the current type
                        // you can also specify what creation parameter types you want to pass to it,
                        // so you could possibly pass in data it might need, or a class that it can use to query the host application
                        ConstructorInfo constructor = type.GetConstructor(System.Type.EmptyTypes);
                        if (constructor != null && constructor.IsPublic)
                        {
                            // lets be friendly and only do things legitimitely by only using valid constructors

                            // we specified that we wanted a constructor that doesn't take parameters, so don't pass parameters
                            ScriptingInterface.IScriptType1 scriptObject = constructor.Invoke(null) as ScriptingInterface.IScriptType1;
                            if (scriptObject != null)
                            {
                                //Lets run our script and display its results
                                MessageBox.Show(scriptObject.RunScript(50));
                            }
                            else
                            {
                                // hmmm, for some reason it didn't create the object
                                // this shouldn't happen, as we have been doing checks all along, but we should
                                // inform the user something bad has happened, and possibly request them to send
                                // you the script so you can debug this problem
                            }
                        }
                        else
                        {
                            // and even more friendly and explain that there was no valid constructor
                            // found and thats why this script object wasn't run
                        }
                    }
                }
            }
        }
    }
}

8
задан AP257 10 December 2009 в 17:29
поделиться

2 ответа

Некоторые вещи здесь не подходят ...

1) После POST рекомендуется выполнить перенаправление. Это позволяет избежать печально известного всплывающего окна, в котором говорится, что вы повторно отправляете форму при использовании кнопки возврата.

2) Вам не нужно говорить if request.method == 'POST' , просто если request.POST . Это облегчает чтение вашего кода.

3) Представление обычно выглядит примерно так:

def myview(request):
    # Some set up operations
    if request.POST:
       form=MyForm(request.POST)
       if form.is_valid():
          # some other operations and model save if any
          # redirect to results page
    form=MyForm()
    #render your form template

Это не означает, что не может быть намного более простых и гораздо более сложных представлений. Но в этом суть представления: если запрос является пост-обработкой формы и перенаправления; если запрос - получить, отобразить форму.

Я не знаю, почему вы получаете ошибку Unicode. Я могу только думать, что это связано с одной из ваших моделей, которую вы не предоставляете. Ошибка, как упоминает spookylukey, в его комментарии, скорее всего, вызвана тем, что вы отправили строку вместо dict в начальный параметр.

Я действительно рекомендую документацию django, в , в частности учебник. , но есть также очень хорошая Django Book .

Все, что было сказано, я думаю, вам нужно что-то вроде:

def search(request, q=None):
    if request.POST:
        form = SearchForm(request.POST) 
        if form.is_valid(): 
           q = form.cleaned_data['q']
           url=reverse('search_results', args=(q,))
           return HttpResponseRedirect(url)
    if q is None:
        form = SearchForm() 
    else: 
        form = SearchForm(initial={'q': q})
    return render_to_response('things/search.html', {
        'form': form,
    })

Обратите внимание, что параметр для инициализации является dict значений полей вашей формы

Надеюсь, что это поможет.

10
ответ дан 5 December 2019 в 11:25
поделиться

Django forms are not particularly helpful for your use case. Also, for a search page, it's much better to use a GET form and maintain state in the URL. The following code is much shorter, simpler and conforms far better to HTTP standards:

def search(request):
    q = request.GET.get('q','').strip()
    results = get_some_results(q)
    render_to_response("things/search.html", {'q': q, 'results': results})

The template:

<form method="GET" action=".">
<p><input type="text" value="{{ q }}" /> <input type="submit" value="Search" /></p>
{% if q %}
   {% if results %}
       Your results...
   {% else %}
       No results
   {% endif %}
{% endif %}
</form>
5
ответ дан 5 December 2019 в 11:25
поделиться
Другие вопросы по тегам:

Похожие вопросы: