【问题标题】:I am unable to update two models at the same time in Django Views.py我无法在 Django Views.py 中同时更新两个模型
【发布时间】:2020-09-14 15:49:14
【问题描述】:

我已经在 How can I update first_name, last_name & email of Django model User and update other field in separate models

但我没有得到合适的解决方案。这就是为什么我将这个问题与那个问题类似。

我有 pages.views.py

from django.shortcuts import render, redirect
from .forms import CreateUserForm
from accounts.models import Account
from django.contrib import messages

def signupPage(request):
    if request.user.is_authenticated:
        return redirect('/')
    else:
        form = CreateUserForm()
        if request.method == 'POST':
            form = CreateUserForm(request.POST)
            if form.is_valid():
                user = form.save()

                # focus on this line
                Account.objects.create(user=user)

                messages.success(request, 'Signup success. Now, you can login.')
                return redirect('login')
            else:
                messages.warning(request, 'Signup failed. Please, try again.')
        context = {'form':form}
        return render(request, 'signup.html', context)

另外,我有 accounts.models.py

from django.db import models
from django.contrib.auth.models import User

class Account(models.Model):

    user = models.ForeignKey(User, null=True, on_delete=models.CASCADE)

    # This field is used for to update django model User
    first_name=models.CharField(max_length=30, null=True, blank=False)
    last_name=models.CharField(max_length=30, null=True, blank=False)
    email = models.EmailField(max_length=30, null=True, blank=True)

    profile_photo = models.ImageField(upload_to='profile', null=True)
    mobile_number = models.PositiveBigIntegerField(null=True)
    date_of_birth = models.DateField(auto_now_add=False, auto_now=False, null= True)
    zip_code = models.IntegerField(null=True)
    address = models.CharField(max_length=225, null=True)
    website = models.URLField(max_length=100, null=True)
    bio = models.CharField(max_length=225, null=True)

Accounts.view.py 中:

from django.shortcuts import render, redirect
from .forms import AccountForm
from .models import Account
from pages.forms import CreateUserForm
from django.contrib import messages
from django.contrib.auth.models import User

首先我尝试了这个:

def profileSettingsPage(request, pid):
    user= User.objects.get(id=pid)
    form = AccountForm(instance=user)
    if request.method == 'POST':
        form = AccountForm(request.POST, request.FILES, instance=user)
        if form.is_valid():

            user.first_name = form.cleaned_data.get('first_name')
            user.last_name = form.cleaned_data.get('last_name')
            user.email = form.cleaned_data.get('email')
            user.save()

            form.save()

            messages.success(request, 'Profile saved.')
        else:
            messages.warning(request, 'Faile to saved profile')
    context = {'form':form}
    return render(request, 'profile-settings.html', context)

但它只会保存 User 模型,而不是 AccountForm。

然后我替换user = request.user。同样,它只保存用户模型,而不是 AccountForm。

我再次替换user = Account.objects.get(id=pid)。然后,我遇到了错误DoesNotExist:帐户匹配查询不存在。

我也试过了

def profileSettingsPage(request, pid):
    form = AccountForm()
    if request.method == 'POST':
        form = AccountForm(request.POST, request.FILES)
        if form.is_valid():
            form.save()
            user = User.objects.get(id=pid)
            user.first_name = form.cleaned_data.get('first_name')
            user.last_name = form.cleaned_data.get('last_name')
            user.email = form.cleaned_data.get('email')
            user.save()
            messages.success(request, 'Profile saved.')
        else:
            messages.warning(request, 'Faile to saved profile')
    context = {'form':form}
    return render(request, 'profile-settings.html', context)

它保存了两个模型,但问题是它创建了一个新模型并将空值保存在 Account 模型的 ForeignKey 中,其他字段按原样保存,并且还使用这些值保存了 User 模型。

现在,我的问题是如何同时更新我在 pages.views.py 和 Django User 模型中创建的 Account 模型?

我对传递实例值感到困惑。 我做的和大家一样吗?还是我做错了什么?

【问题讨论】:

  • user = models.ForeignKey(User, null=True, on_delete=models.CASCADE) 你可以使用 OneToOneFiled 代替 ForeignKey

标签: python django django-models django-forms django-views


【解决方案1】:
class Account(models.Model):

    user = models.OneToOneField(User, null=True, on_delete=models.CASCADE)

    # This field is used for to update django model User
    first_name=models.CharField(max_length=30, null=True, blank=False)
    last_name=models.CharField(max_length=30, null=True, blank=False)
    email = models.EmailField(max_length=30, null=True, blank=True)

    profile_photo = models.ImageField(upload_to='profile', null=True)
    mobile_number = models.PositiveBigIntegerField(null=True)
    date_of_birth = models.DateField(auto_now_add=False, auto_now=False, null= True)
    zip_code = models.IntegerField(null=True)
    address = models.CharField(max_length=225, null=True)
    website = models.URLField(max_length=100, null=True)
    bio = models.CharField(max_length=225, null=True)

def profileSettingsPage(request, pid):
    form = AccountForm()
    if request.method == 'POST':
        user = User.objects.get(id=pid)
        user.first_name = request.POST.get('first_name')
        user.last_name = request.POST.get('last_name')
        user.email = request.POST.get('email')
        user.save()
        instance = Account.objects.get(user=user)
        form = AccountForm(request.POST, request.FILES,instance=instance)
        if form.is_valid():
            form.save()
            messages.success(request, 'Profile saved.')
        else:
            messages.warning(request, 'Faile to saved profile')
    context = {'form':form}
    return render(request, 'profile-settings.html', context)

【讨论】:

  • 在 StackOverflow 的某个地方,我发现 form.cleaned_data.get() 比 request.POST.get() 好。这就是我使用 form.cleaned_data.get() 的原因。我是对的吗?
  • 你没有使用 CreateUserForm 所以我使用了 request.POST
  • 我在 Account Model 上添加了三个字段(first_name、last_name 和 email)以使用 form.cleaned.data.get(),无论如何,谢谢你,它成功了!最后,经过一整天的研究,我得到了正确的解决方案。现在,我可以去睡觉了,因为我感觉睡着了。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-01-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-08-11
  • 2020-07-01
  • 1970-01-01
相关资源
最近更新 更多