Django установить значение по умолчанию как подмножество поля модели ManyToMany - PullRequest
0 голосов
/ 07 февраля 2011
class UserProfile(models.Model):
    project_assignments =  models.ManyToManyField('drawingManager.Project', default=SetDefaultProject(self,default_assignment))
    user =  models.OneToOneField(User)
    default_project

    def SetDefaultProject(self,default_assignment):
        if default_assignment:
            self.default_project = default_assignment
        else:
            self.default_project = #somehow choose newest project

    def __unicode__(self):
        admin_reference = self.user.first_name + self.user.last_name
        return admin_reference

Я пытаюсь добиться следующего поведения.Когда пользователь добавляется, по крайней мере одно назначение проекта устанавливается по умолчанию.И они могут позже, через интерфейс параметров, установить их по умолчанию для любого из подмножества project_assignments.Но мне неясно, когда вы можете использовать внешний ключ и поле «многие ко многим» как простой код на языке Python, а когда нет.

Ответы [ 2 ]

4 голосов
/ 07 февраля 2011

Если я вас правильно понимаю, вы не понимаете, что ForeignKeys и ManyToManyFields возвращают разные вещи.

ForeignKey - это отношение один-ко-многим, причем «один» находится на той стороне, на которую он указывает. Это означает, что если вы определили default_project как ForeignKey, self.default_project возвращает один экземпляр Project, который вы можете использовать и назначить как любой другой экземпляр.

Однако, ManyToManyField - как следует из названия - имеет "много" отношений на обеих сторонах. Таким образом, self.project_assignments не возвращает ни одного экземпляра, он возвращает QuerySet. Именно так Django обрабатывает списки экземпляров, извлеченных из базы данных. Таким образом, вы можете использовать add и remove для управления этим списком или разрезать его, чтобы получить один экземпляр.

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

self.default_project = self.project_assignments.all()[0]

(хотя в реальном коде вы должны были бы защититься от вероятности отсутствия назначений, так что это вызовет IndexError).

1 голос
/ 07 февраля 2011

Я не уверен, что понимаю и что вы подразумеваете под «мне непонятно, когда вы можете использовать внешний ключ и поля« многие ко многим »как просто код Python», но ваш псевдокод будет работать со следующими изменениями:*

def SetDefaultProject(self,default_assignment):
    if default_assignment:
        self.project_assignments.add(default_assignment)
    else:
        self.project_assignments.add(self.project_assignments.latest('id'))
        # note: i don't know what your intent is, so please adapt to your needs
        # the key here is `MyModel.objects.latest('id')` to retrieve the latest object 
        # according to the field specified. 'id', 'date_created', etc.

PS: рекомендуется использовать строчные имена и подчеркивания для имен методов (чтобы не путать их с ClassNameFormatRecommendations)

http://www.python.org/dev/peps/pep-0008/

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...