LINUX.ORG.RU

Ссылка на класс при его инициализации

 


0

1

Вот код

class Partner(models.Model):
    alias = random_alias(model=Partner) 

Нужно, чтобы внутри функции random_alias в переменной model хранилась ссылка на конструктор Partner. Так как я написал не работает. Как сделать правильно?

ПС: Питон второй.

★★★★★

Последнее исправление: sphericalhorse (всего исправлений: 1)

Или хочешь такого?

class Alias(object):
    def __init__(self, model):
        self.model = model

    def __str__(self):
        return "I'm alias for model %s" % self.model

def random_alias(model):
    return Alias(model)

class Boo(object):
    pass
Boo.alias = random_alias(Boo)

print Boo.alias
baverman ★★★
()

Или хочешь странную вещь навроде этого:

class Alias(object):
    def __init__(self, model):
        self.model = model

    def __str__(self):
        return "I'm alias #%s for model %s" % (id(self), self.model)

class random_alias(object):
    def __get__(self, instance, cls):
        return Alias(cls)

class Boo(object):
    alias = random_alias()

a1 = Boo.alias
a2 = Boo.alias

print a1
print a2
baverman ★★★
()
Ответ на: комментарий от baverman

А вот нежданчик. Вместо прооспаться я поспал только четыре часа :)

Первый варинат не подходит, ибо в random_alias должны быть ещё параметры.

sphericalhorse ★★★★★
() автор топика
Ответ на: комментарий от baverman

Хорошо. Я не прав. Начнем шире.

Есть Джанго. В ней есть ОРМ, где есть модели. Все модели должны наследоваться от models.Model.

У меня есть модель Partner, в которой есть поле alias, у которого при создании создается значение по умолчанию (оно устанавливается параметром default). Это самое значение по умолчанию должно быть либо строкой, либо callable (то-есть, как вариант может ещё использовать метод объекта). Мне нужно внутри этого callable проверять, не занят ли тот алиас, который оно хочет вернуть. Для доступа к уже существующим записям в базе используется конструкция КлассМодели.objects, таким образом для проверки, не занят ли алиас, мне нужно внутри этого самого callable делать КлассМодели.objects.filter(alias=alias).count(). Вот изначальная задача.

sphericalhorse ★★★★★
() автор топика

там ещё есть декоратор какой-то такой толи @classmethod .

Bad_ptr ★★★★★
()
Ответ на: комментарий от sphericalhorse

Мне нужно внутри этого callable проверять, не занят ли тот алиас, который оно хочет вернуть.

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

baverman ★★★
()
Ответ на: комментарий от sphericalhorse

Я ниче не понял вообще, но если нужно поле содержащее метод класса (напр конструктор) то делают так:

class A :
    def __init__( self, .. ) : ...
    alias = __init__
или так
class A :
    def __init__( self, .. ) : ...
A.alias = A.__init__

Есно получается unbound method, но нафига в таком ключе bound method, к чему его баундить то?

AIv ★★★★★
()
Ответ на: комментарий от sphericalhorse

АПИкей чтоли хочешь автоматически генерировать при создании? Это лучше в save положить или заставить базу генерировать UUIDы.

zz ★★★★
()
Ответ на: комментарий от baverman

Обязательно напорешься на рейс.

Прошу прощения за мою безграмотность, но что такое рейс?

Обычно, такое делают перегружая save()

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

sphericalhorse ★★★★★
() автор топика

А что-то в таком роде как можно сделать?

class RandomAliasModel(models.Model):
def random_alias(self):
self.objects...


class Partner(RandomAliasModel) :
alias = models.CharField(
default=random_alias_test(),
)

sphericalhorse ★★★★★
() автор топика
Ответ на: комментарий от sphericalhorse
def foo():
    outer_frame = inspect.getouterframes (inspect.currentframe())
    return outer_frame[1][0].f_locals['self'].model.objects

Но лучше возвращай в дефолт что ты хочешь, а проверяй при сохранении.

zz ★★★★
()
Ответ на: комментарий от sphericalhorse

но что такое рейс?

http://ru.wikipedia.org/wiki/Состояние_гонки

Что если два пользователя админки захотят добавить объект одновременно и у них сгенерится одинаковый алиас? Во время сейва один их них превратится в тыкву.

чтобы этот самый, случайный алиас было видно в админке уже при создании материала

Можно, но только при сохранении пользователь должен быть готов, что он изменится.

baverman ★★★
()
Ответ на: комментарий от baverman

Что если два пользователя админки захотят добавить объект одновременно и у них сгенерится одинаковый алиас?

У этого крайне малая вероятность. Предполагается, что у сайта будет один администратор, малое число материалов и достаточно случайный алиас.

sphericalhorse ★★★★★
() автор топика
Ответ на: комментарий от baverman

Так а unique=True не защитит от этого самого состояния гонки?


ПС: решил написать свой тип поля, это должно решить проблему.

sphericalhorse ★★★★★
() автор топика
Ответ на: комментарий от baverman

При попытке записать в базу, кинется исключение.

Пользователю в админке напишет, что такой алиас занят. Меня полностью устраивает.

И ещё один вопрос не по теме поста.

Можно ли в Джанге внутри конструктора поля узнать название поля?

То есть так

class MyField(model.Field):
    def __init__(self, *args, **kwargs):
        print %магический способ узнать название поля%
        ...
...
class MyModel(models.Model):
    hello = MyFiled() # выведет в stdout: hello

sphericalhorse ★★★★★
() автор топика
Ответ на: комментарий от sphericalhorse

Можно ли в Джанге внутри конструктора поля узнать название поля?

AFAIK, нет. Это становится известно позже.

baverman ★★★
()

Короче я вижу, что у меня сделать так, как я хочу не получиться. Сделал глупо, зато просто и работает:

default = ''.join(random.sample(string.lowercase, 10))

sphericalhorse ★★★★★
() автор топика
Ответ на: комментарий от sphericalhorse

Если это в конструкторе - то это не callable, оберни в лямбду. Если это в своем поле - там можно переопределить has_default и get_default в последнем будет доступно self.name инфа 97%.

zz ★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.