2013-03-27 2 views
1

Я работаю над проектом в Django, и у меня есть следующая проблема:Джанго Присвоить M2M после сохранения

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

self.user.add(*self.team.users.all()) 
self.save() 

И это не работает.

Пробовал итерация:

for uTeam in self.team.users.all(): 
    self.users.add(uTeam) 

и не работает.

Единственный способ, который работает для меня, но только в Django Shell:

P = Project.objects.get(pk=1) 
T = Team.objects.get(pk=1) 
P.user.add(*T.user.all()) 
P.save() 

Это решение, которое у меня есть ниже, но не работает в Django (дает бесконечный цикл)

class Team(models.Model): 
    name = models.CharField(max_length=200, 
          help_text=_('name of the team')) 
    user = models.ManyToManyField(settings.AUTH_USER_MODEL, 
           related_name="members_of_team", 
           help_text=_('users of the team'), 
           null=True 
           ) 
    and more.... 


class Project(models.Model): 
    id = models.AutoField(primary_key=True, null=False) 
    name = models.CharField(max_length=200, 
          help_text=_('name of project'), 
          ) 
    team = models.ForeignKey(Team,`enter code here` 
          on_delete=models.PROTECT, 
          help_text=_('team of project')) 
    created_by = models.ForeignKey(settings.AUTH_USER_MODEL, 
            on_delete=models.PROTECT, 
            related_name='creator_project', 
            blank=True, 
            null=False, 
            help_text=_('project created by')) 
    customer = models.ForeignKey(Customer, 
           on_delete=models.PROTECT, 
           help_text=_('customer')) 
    user = models.ManyToManyField(settings.AUTH_USER_MODEL, 
            related_name='users_team', 
            blank=True, 
            null=False, 
            help_text=_('users of this project')) 


    def save(self, *args, **kwargs): 

    if self.checkIntegrity(): 
     super(Project, self).save(*args, **kwargs) 
     if self.user.all().count() < self.team.user.all().count(): 
     T = Team.objects.get(pk=self.team.id) 
     P = Project.objects.get(pk=self.id) 
     P.user.add(*T.user.all()) 
     P.save() 

Спасибо за вашу помощь

+0

только для уточнения - добавление пользователей к проекту перед тем, как сохранить сам проект, создает исключение, потому что проект еще не имеет первичного ключа, поэтому вы не можете назначить пользователю (в этот момент) несуществующий проект. Далее - afaik не должно быть никакой разницы между добавлением пользователей на итерации (вторая попытка) и добавлением их в список (ваш текущий код в 'save()'). У вас была некоторая информация об отладке, если она действительно зациклилась на этот цикл? – yedpodtrzitko

+0

Что происходит с тем, что P.save() вызывает сохранение Project и проверяет целостность, вызывает super (Project, Self), снова назначает T и P и добавляет пользователей в другое время ... Я заметил, что это назначено, но входит в бесконечный цикл, который через некоторое время получает значение «RuntimeError: максимальная глубина рекурсии» – Charlisim

+0

yep, это имеет смысл. Но вызов 'P.save()' (самая последняя строка не обязательна, правильно? – yedpodtrzitko

ответ

0

Я получил его, я прочитал, что поля М2М заполняются после сохранения() и post_save(), и есть сигнал, который срабатывает, когда поле M2M изменяется таким образом, я Wr ite:

@receiver(m2m_changed, sender=Project.user.through) 
def m2mChange(sender, **kwargs): 
    instance = kwargs['instance'] 
    T = Team.objects.get(pk=instance.team.id) 
    if kwargs['pk_set'] is None: 
     instance.user.add(*T.user.all()) 

И теперь он отлично работает. Спасибо вам всем.

Смежные вопросы