2015-05-21 5 views
1

У меня есть модель EntryКак избежать рекурсии при сохранении Джанго модели

Теперь, когда Entry создан для любой даты. Затем перед сохранением мне нужно сделать проверку и добавить дополнительные записи, например, например.

Entry 1 - red

Теперь предположим, что если entry.color = red Тогда мне также нужно сделать еще две записи, как

Entry 2 - red2 
Entry 3 - red3 

Теперь я поставил это в pre_save сигнал

@receiver(pre_save, sender=Entry) 
def new_entries(sender, instance, *args, **kwargs): 
    pass 

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

Вставьте эту логику так, чтобы рекурсия не возникала?

+2

Что именно вы пытаетесь достичь? – Wtower

+0

@ В основном его нужно разбить запись, если новая запись перекрывается во времени с предыдущей. – user3214546

+0

Вам нужно создать новые записи в той же модели и необходимо ли их создавать до создания новой записи этой модели? Пожалуйста, укажите более подробную информацию. – chaos

ответ

2

я бы решить с дополнительным аргументом, чтобы сэкономить, в отличие от присоединения к pre_save:

import django.db.models 
class Entry(models.Model): 
    color=models.CharField(max_length="50") 
    def save(self,create_children=True,**kwargs): 
     if create_children and not self.pk: 
      result = super(Entry,self).save(**kwargs) 
      Entry(color=self.color).save(create_children=False) 
      Entry(color=self.color).save(create_children=False) 
     else: 
      result = super(Entry,self).save(**kwargs) 
     return result 

Вы хотите, чтобы убедиться, что вы называете super(Entry,self).save(**kwargs), прежде чем вы на самом деле построить детей, в противном случае вы будете засорять базу данных с моделями, когда super() поднимает IntegrityError

+0

как я использую django rest serializer для сохранения, нужно ли мне что-то возвращать в конце сохранения? – user3214546

0

Я думаю, у вас должно быть 2 отдельных модели для этого. Ваш «родитель» Entry может быть подклассом основной модели Entry, так что только ИТ создает новые дочерние записи.

class Entry(models.Model): 
    pass 
    # whatever you need here 

class ParentEntry(Entry): 

    @receiver(pre_save, sender=ParentEntry) 
    def new_entries(sender, instance, *args, **kwargs): 
     pass 

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

+0

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

0

что-то, как это должно работать:

class Entry(model.Model): 

    def save(self, color, create_more=True, *args, **kwargs): 
     if self.pk is None: # this is a new Entry    
      if create_more: 
       new_color = '%s2' % color 
       Entry(color=new_color, create_more=False).save() 

     super(Entry, self).save(...) 

Тхо Я подозреваю, что это лучший способ, но я не могу сказать, не зная более подробную информацию о том, что вы пытаетесь сделать.

+0

Осторожно с тем, что передано для сохранения. Для этой реализации требуется, чтобы экземпляр вызывался как: «Entry (color =« blue »). Save (« blue »)', см. Мой ответ, чтобы посмотреть, как этого избежать. –

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