【问题标题】:How to update only specific fields in django model?如何仅更新 django 模型中的特定字段?
【发布时间】:2020-09-18 04:27:23
【问题描述】:

我只想更新模型中的特定字段。 这是我的models.py

class Teacher(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    image = models.ImageField(upload_to='teacher/images')
    phone = models.CharField(max_length=15)
    address = models.CharField(max_length=25)
    salary = models.DecimalField(max_digits=20, decimal_places=2)
    joindate = models.DateField(auto_now_add=True)
    status = models.BooleanField(default=True)

这是我的forms.py

class TeacherForm(forms.ModelForm):
    class Meta:
        model = User
        fields = ['first_name', 'last_name', 'username', 'email', 'password']


class TeacherExtraForm(forms.ModelForm):
    class Meta:
        model = models.Teacher
        fields = ['phone', 'address', 'salary', 'status', 'image']

这是我的观点.py

def update_teacher(request, pk):
    teacher = models.Teacher.objects.get(id=pk)
    user = models.User.objects.get(id=teacher.user_id)
    form1 = forms.TeacherForm(instance=user)
    form2 = forms.TeacherExtraForm(instance=teacher)
    context = {
        'teacher': teacher,
        'user': user,
        'form1': form1,
        'form2': form2
    }
    if request.method == 'POST':
        form1 = forms.TeacherForm(request.POST, instance=user)
        form2 = forms.TeacherExtraForm(request.POST, instance=teacher)
        if form1.is_valid() and form2.is_valid():
            user = form1.save(commit=False)
       
            user.save(update_fields=['first_name', 'last_name', 'email', 'username'])
            f2 = form2.save(commit=False)
            f2.status = True
            f2.save(update_fields=['phone', 'address', 'salary', 'status'])
            return redirect('Teacher:teacher_index')
    return render(request, 'Teacher/update_teacher.html', context)

这里我只想更新名字、姓氏、电子邮件、用户名、电话、地址、薪水和状态,而不影响密码和图像字段。当我也添加密码和图像字段时,它可以工作,但我不想在这里更新密码和图像。

【问题讨论】:

  • TeacherForm中删除字段。
  • 那么如何在添加时为老师创建密码和图像。
  • 这能回答你的问题吗? Django partial update
  • @sd077:您制作了两个表单,一个用于创建,一个用于更新。

标签: django


【解决方案1】:

通常在这种情况下,一种制作两种形式,一种用于创建,一种用于更新。例如,Django 本身有一个UserCreateForm [Django-doc] 和一个UserChangeForm [Django-doc]。因此,我们可以构造另外两种形式:

class TeacherUpdateForm(forms.ModelForm):
    class Meta:
        model = User
        fields = ['first_name', 'last_name', 'username', 'email']

class TeacherUpdateExtraForm(forms.ModelForm):
    class Meta:
        model = models.Teacher
        fields = ['phone', 'address', 'salary', 'status']

在视图中,我们因此使用这些表单:

from django.shortcuts import get_object_or_404

def update_teacher(request, pk):
    teacher = get_object_or_404(models.Teacher, pk=pk)
    user = teacher.user
    if request.method == 'POST':
        form1 = forms.TeacherUpdateForm(request.POST, instance=user)
        form2 = forms.TeacherUpdateExtraForm(request.POST, instance=teacher)
        if form1.is_valid() and form2.is_valid():
            form1.save()
            from2.instance.status = True
            form2.save()
            return redirect('Teacher:teacher_index')
    else:
        form1 = forms.TeacherUpdateForm(instance=user)
        form2 = forms.TeacherUpdateExtraForm(instance=teacher)
    context = {
        'teacher': teacher,
        'user': user,
        'form1': form1,
        'form2': form2
    }
    return render(request, 'Teacher/update_teacher.html', context)

【讨论】:

  • 我也相信 update_fields 应该可以工作。上面的代码有问题吗?
  • @sd077:如果需要密码、图片等并且丢失,表单将拒绝它。所以问题不在于update_fields 的问题,而在于旨在进行适当验证的表单。因此问题出现在form1.is_valid() and form2.is_valid()
  • @sd077: 可能不会,因为passwordimage 没有默认值,而且它们也不是null=True,那么在这种情况下表单应该做什么?但我认为你正在解决错误的问题。表单旨在与用户交互,而不是模型。因此,与其尝试将模型“调整”到用户交互,通常情况下表单应该这样做。模型不应针对用例设计,它们应旨在为任何应用程序正确存储和表示数据。
  • 感谢您的回答。请问最后一个问题。如果我只想从教师资料中更新(或更改)教师形象怎么办。我该如何更新?
  • @sd077:您制作了一个仅将image 作为字段的表单(当然您将request.FILES 传递给表单)。这看起来有点类似于同样只更改密码的SetPasswordFormdocs.djangoproject.com/en/3.0/topics/auth/default/…
猜你喜欢
  • 2015-01-28
  • 2016-10-18
  • 1970-01-01
  • 2012-12-03
  • 2013-10-22
  • 2015-09-14
  • 2021-06-05
  • 1970-01-01
相关资源
最近更新 更多