Запуск данных другой модели для изменения (M2M) на основе этой модели - PullRequest
1 голос
/ 12 марта 2011

Обычно я пытаюсь использовать данные из одной модели для запуска переключения в другой модели.

Если мой объект счета связан с файлом, я хочу, чтобы файл был "заблокирован" (логическое значение).

Я обнаружил, что когда я сохраняю счет-фактуру, после связывания его с файлом, он не регистрирует, что invoice_file.count () равен> 0 - пока в следующий раз я не открою счет и не сохранюэто снова.Обратите внимание, что я выполняю оценку после вызова super (), поэтому, на мой взгляд, это в лучшем случае сбивает с толку.

class Invoice(models.Model):
...
invoice_file = models.ManyToManyField(UploadFile, null = True, blank = True)
    def save(self, *args, **kwargs):
        print('Invoice: saving!')
        super(Invoice, self).save(*args, **kwargs)
        print 'invoice_file count: %i' % self.invoice_file.count()
        if self.invoice_file.count() > 0:
            for invoice_file in self.invoice_file.all():
                if(invoice_file.locked_status(1)) != 1: raise Exception('Couldn\'t set file locked status to 1 on file %s' % invoice_file.filename)

Это вызывает функцию в модели UploadFile:

class UploadFile(models.Model):
...
def locked_status(self, stat):
    print('Locked status called.')
    if stat == 1:
        self.locked = True
        self.save()
        return 1
    elif stat == 0:
        self.locked = False
        self.save()
        return 0

def save(self, *args, **kwargs):
    print 'UploadFile: Saving!'
    super(UploadFile, self).save(*args, **kwargs)

1 Ответ

2 голосов
/ 12 марта 2011

Удалите следующую строку:

if self.invoice_file.count() > 0:

Если вы собираетесь выполнить попадание в базу данных, вы также можете сделать это, получив все файлы, связанные со счетом.Это должно иметь дополнительное преимущество при получении «свежего» представления связанных объектов.

Хотя проблема, вероятно, еще глубже.Поля ManyToMany не могут быть сохранены, пока не будет сохранена содержащая их модель.Пример:

class Post(models.Model):
    title = models.CharField(max_length=100)
    commenters = models.ManyToManyField(User)

me = User.objects.get(username='Josh')
p = Post(title="ManyToManyExample")
p.commenters.add(me) # error, Post does not yet have an ID.
p.save()
p.commenters.add(me) # success!

Ваше поле invoice_file имеет неверное имя.Он должен называться invoice_files, поскольку это коллекция.В вашем методе Invoice.save вы пытаетесь перебрать связанную коллекцию, прежде чем добавите UploadFile s в эту коллекцию.Я бы предложил добавить метод к вашей Invoice модели.

class Invoice(models.Model):
    ...

    def add_invoice_file(self, uploaded_file):
        self.invoice_files.add(uploaded_file) # error if the Invoice hasn't been saved yet
        for invoice_file in self.invoice_files.all(): 
            status = invoice_file.locked_status(1)
            if status != 1:
                raise Exception('Blah')

Если Счет-фактура связан с большим количеством файлов, вместо использования .all(), вам следует сделать self.invoice_files.filter(locked=False).В любом случае, это может даже стоить того, чтобы избежать большого количества ненужных сохранений базы данных.

...