如何在Django ModelForm中更改数据?

时间:2015-08-14 09:56:06

标签: python django django-models django-forms

models.py

class Playlist(models.Model):
    name = models.CharField(max_length=50)
    num_of_songs = models.IntegerField(max_length=15)
    duration = models.IntegerField()
    owner = models.ForeignKey(settings.AUTH_USER_MODEL, null=True, blank=True)
    songs = models.ManyToManyField("Song", blank=True)

forms.py

class PlaylistEditForm(forms.ModelForm):
    class Meta:
        model = Playlist
        fields = ['name', 'songs']

根据我从表单中获得的歌曲计算durationnum_of_songs。但我从一个角度来看这个计算。

views.py

playlist = Playlist.objects.get(id=playlist_id)

if request.method == 'POST':
    form = PlaylistEditForm(request.POST, instance=playlist)
    if form.is_valid():
        form.save()
        playlist.duration = playlist.songs.aggregate(Sum('duration'))['duration__sum'] or 0
        playlist.num_of_songs = playlist.songs.count()
        playlist.save()

我想在表单中计算durationnum_of_songs

2 个答案:

答案 0 :(得分:2)

您可以将计算结果移到覆盖表单save方法

的表单中
def save(self, commit=True):
    instance = super(PlaylistEditForm, self).save(commit=False)
    instance.duration = instance.songs.aggregate(Sum('duration'))['duration__sum'] or 0
    instance.num_of_songs = instance.songs.count()
    if commit:
        instance.save()
    return instance

,您的观点变为

playlist = Playlist.objects.get(id=playlist_id)

if request.method == 'POST':
    form = PlaylistEditForm(request.POST, instance=playlist)
    if form.is_valid():
        form.save()

请参阅Django的official docs了解更多信息。

答案 1 :(得分:0)

有没有理由不在模型save()方法中执行此操作?如果在表单save()方法中使用它,则如果保存模型实例而不是从模型表单中保存模型实例,则数据库中的duration和num_of_songs将不会更新。

class Playlist(models.Model):
    name = models.CharField(max_length=50)
    num_of_songs = models.IntegerField(max_length=15)
    duration = models.IntegerField()
    owner = models.ForeignKey(settings.AUTH_USER_MODEL, null=True, blank=True)
    songs = models.ManyToManyField("Song", blank=True)

    def save(self, *args, **kwargs):
        if self.pk:
            self.duration = self.songs.aggregate(Sum('duration'))['duration__sum'] or 0
            self.num_of_songs = self.songs.count()
        return super(Playlist, self).save(*args, **kwargs)

您将查看:

if request.method == 'POST':
    form = PlaylistEditForm(request.POST, instance=playlist)
    if form.is_valid():
        playlist = form.save()