Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/django/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何更改Django ModelForm中的数据?_Python_Django_Django Models_Django Forms - Fatal编程技术网

Python 如何更改Django ModelForm中的数据?

Python 如何更改Django ModelForm中的数据?,python,django,django-models,django-forms,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=Tru

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']
我根据从表单中获得的歌曲计算
持续时间
歌曲数
。但我是从一个角度来计算的

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()

我想计算表单中的
持续时间
歌曲数

是否有任何理由不在models
save()
方法中执行此操作?如果在forms save()方法中有它,则如果保存模型实例而不是从modelform保存,则不会更新数据库中歌曲的持续时间和数量

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()    

您可以将计算移动到表单,覆盖表单的
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's以了解更多信息。

您可以将计算移到覆盖其
的表单中。保存
方法您提出了一个好问题。我试过了,但没用。save方法的问题是它试图从数据库中读取数据。假设我正在从django管理页面创建一个新的播放列表对象。它如何对数据库中不存在的对象调用聚合和计数方法?这就是为什么我要更改表单保存方法,现在我需要将该表单导入django ModelAdmin。除非我错了,你知道更好的方法,请告诉我。你是对的。我添加了检查对象是否存在的
if self.pk
。但这并不理想。另一种可能是使用djangos
post_save signal