Django моделирует: Почему столкновение имени?

Во-первых, я знаю, как решить проблему, я просто пытаюсь понять, почему она происходит. Сообщение об ошибке:

users.profile: Обратное имя запроса для поля 'обращается' к столкновениям со смежной областью 'Address.profile'. Добавьте related_name rgument к определению для 'адреса'.

И код:

class Address(models.Model):
    country = fields.CountryField(default='CA')
    province = fields.CAProvinceField()
    city = models.CharField(max_length=80)
    postal_code = models.CharField(max_length=6)
    street1 = models.CharField(max_length=80)
    street2 = models.CharField(max_length=80, blank=True, null=True)
    street3 = models.CharField(max_length=80, blank=True, null=True)

class Profile(Address):
    user = models.ForeignKey(User, unique=True, related_name='profile')
    primary_phone = models.CharField(max_length=20)
    address = models.ForeignKey(Address, unique=True)

Если я понимаю правильно, эта строка:

address = models.ForeignKey(Address, unique=True)

Заставит атрибут быть добавленным к Address класс с именем profile. Что создает другое имя "профиля"?


Что, если мне не нужно обратное имя? Существует ли способ отключить его? Адреса используются для дюжины вещей, таким образом, большинство обратных отношений будет пробелом так или иначе.

Существует ли способ скопировать поля адреса в модель вместо того, чтобы иметь отдельную таблицу для адресов? Без наследования Python (это не имеет смысла, и если Модель имеет 2 адреса, она не работает).

7
задан mpen 7 February 2010 в 21:56
поделиться

2 ответа

Две вещи:

1), как говорят другие, метод должен иметь следующую подпись.

-(void) trigger:(NSTimer *) theTimer;

и вы делаете таймер таким образом:

nst = [NSTimer timerWithTimeInterval:1.0 target:self selector:@selector(trigger:) userInfo:nil repeats:YES];

2) просто создание таймера не запускает его. Как указано в в документации :

Необходимо добавить новый таймер в прогон цикл, используя addTimer: forMode:. Затем, по истечении секунд таймер срабатывает, вызывая вызов. (Если таймер сконфигурирован для повторения, там нет необходимости в последующем повторном добавлении таймер для цикла выполнения.)

Вот часть реального функционирующего кода, который можно смоделировать после. Создание таймера совпадает с вашим, но также добавляет его в runloop правильным путь.

[[NSRunLoop currentRunLoop] addTimer:
     [NSTimer timerWithTimeInterval:0.1
                             target:self
                           selector:@selector(someSelector:)
                           userInfo:nil
                            repeats:NO]
                                 forMode:NSDefaultRunLoopMode];
-121--4180406-

Классическая готча в этом сценарии - что делать с людьми, родившимися 29 февраля. Пример: нужно быть в возрасте 18 лет, чтобы проголосовать, водить машину, покупать алкоголь и т.д. если вы родились 2004-02-29, какой первый день вам разрешено делать такие вещи: 2022-02-28 или 2022-03-01? AFAICT, в основном первый, но несколько убийств может сказать последний.

Вот код, который обслуживает 0,068% (прим) населения, родившегося в этот день:

def age_in_years(from_date, to_date, leap_day_anniversary_Feb28=True):
    age = to_date.year - from_date.year
    try:
        anniversary = from_date.replace(year=to_date.year)
    except ValueError:
        assert from_date.day == 29 and from_date.month == 2
        if leap_day_anniversary_Feb28:
            anniversary = datetime.date(to_date.year, 2, 28)
        else:
            anniversary = datetime.date(to_date.year, 3, 1)
    if to_date < anniversary:
        age -= 1
    return age

if __name__ == "__main__":
    import datetime

    tests = """

    2004  2 28 2010  2 27  5 1
    2004  2 28 2010  2 28  6 1
    2004  2 28 2010  3  1  6 1

    2004  2 29 2010  2 27  5 1
    2004  2 29 2010  2 28  6 1
    2004  2 29 2010  3  1  6 1

    2004  2 29 2012  2 27  7 1
    2004  2 29 2012  2 28  7 1
    2004  2 29 2012  2 29  8 1
    2004  2 29 2012  3  1  8 1

    2004  2 28 2010  2 27  5 0
    2004  2 28 2010  2 28  6 0
    2004  2 28 2010  3  1  6 0

    2004  2 29 2010  2 27  5 0
    2004  2 29 2010  2 28  5 0
    2004  2 29 2010  3  1  6 0

    2004  2 29 2012  2 27  7 0
    2004  2 29 2012  2 28  7 0
    2004  2 29 2012  2 29  8 0
    2004  2 29 2012  3  1  8 0

    """

    for line in tests.splitlines():
        nums = [int(x) for x in line.split()]
        if not nums:
            print
            continue
        datea = datetime.date(*nums[0:3])
        dateb = datetime.date(*nums[3:6])
        expected, anniv = nums[6:8]
        age = age_in_years(datea, dateb, anniv)
        print datea, dateb, anniv, age, expected, age == expected

Вот вывод:

2004-02-28 2010-02-27 1 5 5 True
2004-02-28 2010-02-28 1 6 6 True
2004-02-28 2010-03-01 1 6 6 True

2004-02-29 2010-02-27 1 5 5 True
2004-02-29 2010-02-28 1 6 6 True
2004-02-29 2010-03-01 1 6 6 True

2004-02-29 2012-02-27 1 7 7 True
2004-02-29 2012-02-28 1 7 7 True
2004-02-29 2012-02-29 1 8 8 True
2004-02-29 2012-03-01 1 8 8 True

2004-02-28 2010-02-27 0 5 5 True
2004-02-28 2010-02-28 0 6 6 True
2004-02-28 2010-03-01 0 6 6 True

2004-02-29 2010-02-27 0 5 5 True
2004-02-29 2010-02-28 0 5 5 True
2004-02-29 2010-03-01 0 6 6 True

2004-02-29 2012-02-27 0 7 7 True
2004-02-29 2012-02-28 0 7 7 True
2004-02-29 2012-02-29 0 8 8 True
2004-02-29 2012-03-01 0 8 8 True
-121--1833887-

Я не уверен, откуда идет ошибочное поле профиля ... Но один из способов выяснить будет: временное удаление адрес = модели. Foreign Key (...) из профиля, ./manage.py shell , из... import address (импортировать адрес), затем просмотрите, что скажет Address.profile .

Я не думаю, что существует какой-либо официальный способ наследования только полей из какой-то другой модели без использования наследования... Но вы можете подделать его так (где SourceModel есть, например, Адрес и TargetModel есть, например, Профиль ):

for field in SourceModel._meta.fields:
    TargetModel.add_to_class(field.name, copy.deepcopy(field))

(это происходит из ModelBase Джанго __ новая __ реализация )

1
ответ дан 6 December 2019 в 07:06
поделиться

Я не думаю, что возможно отключить обратное имя.

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

0
ответ дан 6 December 2019 в 07:06
поделиться
Другие вопросы по тегам:

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