Django - 无法分配 - 必须是一个实例

Django - cannot assign - must be an instance

我最近尝试对这个问题进行措辞,但完全搞糊涂了。我在 models.py:

中用这个扩展了默认用户模型
class Biography(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    biography = models.TextField(max_length=500, blank=True,default='Details')

我已将其包含在 forms.py 中:

class EditProfileForm(forms.Form):
    first_name = forms.CharField(label='First Name')
    last_name = forms.CharField(label='Last Name')
    biography = forms.CharField(label='Biography', widget=Textarea(attrs={'rows': 5}))

我想编辑配置文件并想添加 "biography",但完全不知道从哪里开始。视图如下:

def edit_profile(request):
    user = request.user
    products = Product.objects.filter(user=user)
    form = EditProfileForm(request.POST or None, initial={'first_name':user.first_name, 'last_name':user.last_name})
    if request.method == 'POST':
        if form.is_valid():
            user.first_name = request.POST['first_name']
            user.last_name = request.POST['last_name']
            user.save()
            return render(request, 'profile.html', {'user':user, 'products':products})
    context = {"form": form}
    return render(request, "edit_profile.html", context)

我试图用这个复制已经存在的东西:

def edit_profile(request):
    user = request.user
    products = Product.objects.filter(user=user)
    biography = Biography(user=user)
    form = EditProfileForm(request.POST or None, initial={'first_name':user.first_name, 'last_name':user.last_name, 'biography':user.biography})
    if request.method == 'POST':
        if form.is_valid():
            user.first_name = request.POST['first_name']
            user.last_name = request.POST['last_name']
            user.biography = request.POST['biography']
            user.save()
            return render(request, 'profile.html', {'user':user, 'products':products})
    context = {"form": form}
    return render(request, "edit_profile.html", context)

不知何故,我肯定错过了重点。上次我问这个问题时,我有点被责备了,因为我不知道如何解决它。老实说,我对 Django 真的很陌生,很惊讶我能走到这一步,但我被卡住了。我 'think' 我需要创建一个实例,但不确定如何创建。

user.biographyBiography 模型的一个实例,所以您在这里应该做的是获取该实例并编辑其属性,如下所示:

bio = user.biography
bio.biography = request.POST['biography']
bio.save()

你应该做的不同:

  1. 创建 Biography 实例,如果不存在,或者从数据库中获取。
  2. 为不同的请求方法实例化单独的表单
  3. 使用cleaned_data作为输入验证是表单的主要用途之一
  4. 总是在 POST
  5. 之后重定向
  6. 分别保存 UserBiography 个实例
  7. 并且您不需要在表单视图中使用相关 products。如果你不打算在这里更新它们就好了。

例如:

def edit_profile(request):
    user = request.user
    biography, created = Biography.objects.get_or_create(user=user)
    form = EditProfileForm(initial={
        'first_name': user.first_name,
        'last_name': user.last_name,
        'biography': biography.biography
    })

    if request.method == 'POST':
        form = EditProfileForm(data=request.POST)
        if form.is_valid():
            user.first_name = form.cleaned_data['first_name']  # use cleaned_data
            user.last_name = form.cleaned_data['last_name']
            biography.biography = form.cleaned_data['biography']
            biography.save()  # save Biography object
            user.save()  # save User object
            return redirect(biography)  #  always redirect after successful POST. In this case Biography must have get_absolute_url() method

    context = {'form': form}
    return render(request, 'edit_profile.html', context)

documentation 阅读更多内容。