Django-администратор: CharField как TextArea

Я написал эту небольшую функцию несколько лет назад:

function sqlvprintf($query, $args)
{
    global $DB_LINK;
    $ctr = 0;
    ensureConnection(); // Connect to database if not connected already.
    $values = array();
    foreach ($args as $value)
    {
        if (is_string($value))
        {
            $value = "'" . mysqli_real_escape_string($DB_LINK, $value) . "'";
        }
        else if (is_null($value))
        {
            $value = 'NULL';
        }
        else if (!is_int($value) && !is_float($value))
        {
            die('Only numeric, string, array and NULL arguments allowed in a query. Argument '.($ctr+1).' is not a basic type, it\'s type is '. gettype($value). '.');
        }
        $values[] = $value;
        $ctr++;
    }
    $query = preg_replace_callback(
        '/{(\\d+)}/', 
        function($match) use ($values)
        {
            if (isset($values[$match[1]]))
            {
                return $values[$match[1]];
            }
            else
            {
                return $match[0];
            }
        },
        $query
    );
    return $query;
}

function runEscapedQuery($preparedQuery /*, ...*/)
{
    $params = array_slice(func_get_args(), 1);
    $results = runQuery(sqlvprintf($preparedQuery, $params)); // Run query and fetch results.   
    return $results;
}

Это позволяет запускать операторы в однострочном C # -ish String.Format, например:

runEscapedQuery("INSERT INTO Whatever (id, foo, bar) VALUES ({0}, {1}, {2})", $numericVar, $stringVar1, $stringVar2);

Он избегает использования типа переменной. Если вы попытаетесь параметризовать имена таблиц и столбцов, это будет терпеть неудачу, поскольку она помещает каждую строку в кавычки, которая является недопустимым синтаксисом.

ОБНОВЛЕНИЕ БЕЗОПАСНОСТИ: предыдущая версия str_replace разрешала инъекции, добавляя токены {#} в пользовательские данные. Эта версия preg_replace_callback не вызывает проблем, если замена содержит эти токены.

79
задан Soviut 5 March 2011 в 20:56
поделиться

4 ответа

Необходимо будет создать forms.ModelForm, который опишет, как Вы хотите descr поле быть отображенными, и затем сказать admin.ModelAdmin использовать ту форму. Например:

from django import forms
class CabModelForm( forms.ModelForm ):
    descr = forms.CharField( widget=forms.Textarea )
    class Meta:
        model = Cab

class Cab_Admin( admin.ModelAdmin ):
    form = CabModelForm

form атрибут admin.ModelAdmin документируется в документацию чиновника Django. Вот одно место для рассмотрения .

89
ответ дан IntrepidDude 24 November 2019 в 10:07
поделиться

Для этого случая наилучший вариант состоит в том, чтобы, вероятно, только использовать TextField вместо CharField в Вашей модели. Можно также переопределить formfield_for_dbfield метод Вашего ModelAdmin класс:

class CabAdmin(admin.ModelAdmin):
    def formfield_for_dbfield(self, db_field, **kwargs):
        formfield = super(CabAdmin, self).formfield_for_dbfield(db_field, **kwargs)
        if db_field.name == 'descr':
            formfield.widget = forms.Textarea(attrs=formfield.widget.attrs)
        return formfield
52
ответ дан Carl Meyer 24 November 2019 в 10:07
поделиться

Можно разделить собственное поле на подклассы с необходимым formfield метод:

class CharFieldWithTextarea(models.CharField):

    def formfield(self, **kwargs):
        kwargs.update({"widget": forms.Textarea})
        return super(CharFieldWithTextarea, self).formfield(**kwargs)

Это возьмет влияние на всех сгенерированных формах.

13
ответ дан Ashish Gupta 24 November 2019 в 10:07
поделиться

Вместо models.CharField, используйте models.TextField для descr.

4
ответ дан mipadi 24 November 2019 в 10:07
поделиться
Другие вопросы по тегам:

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