Сохранение значений в другую таблицу базы данных с отношением "один к одному" в Django во время обновления формы
Это моя models.py
с 2 таблицами, имеющими отношения один-к-одному. Модель UserComputedInfo
имеет отношения один-к-одному с моделью CustomUser.
from django.contrib.auth.models import AbstractUser
from django.db import models
from django.contrib.auth import get_user_model
class CustomUser(AbstractUser):
email = models.EmailField(unique=True)
post_code = models.DecimalField(max_digits=9, decimal_places=6)
def __str__(self):
return self.username
class UserComputedInfo(models.Model):
user = models.OneToOneField(get_user_model(), on_delete=models.CASCADE)
copy_input = models.DecimalField(max_digits=9, decimal_places=6)
def __str__(self):
return self.copy_input
Вот соответствующий раздел моего views.py
.
from django.shortcuts import redirect
from django.contrib import messages
def profile(request, username):
if request.method == "POST":
user = request.user
form = UserUpdateForm(request.POST, request.FILES, instance=user)
if form.is_valid():
user_form = form.save()
# How to save post_code to copy_input in UserComputedInfo model
messages.success(request, f'{user_form.username}, Your profile has been updated!')
return redirect("profile", user_form.username)
return redirect("homepage")
После того, как пользователь отправит форму, будет запущена функция profile
и post_code
в модели CustomUser
будет обновлено. Я хочу скопировать содержимое post_code
в copy_input
в модели UserComputedInfo
также.
Как мне сделать это внутри моего файла views.py?
Я использую Django v4 и Windows 10.
Если я правильно вас понял, то для того, чтобы подменить переменную другого класса в том же файле, это будет выглядеть так:
#pyfile.py
class test:
num=1
test().num=2
print(test().num)
Но если вы хотите изменить его из другого файла, убедитесь, что оба файла находятся в одном каталоге, затем используйте:
#pyfile2.py
from pyfile import Test
Test().num=3
print(Test().num
Если это не то, что вы имели в виду, дайте мне больше объяснений по этому вопросу.
if form.is_valid():
custom_user = form.save(commit=False)
custom_user.user_computed_info.copy_input = custom_user.post_code
custom_user.save()
custom_user.user_computed_info.save() # This may not be necessary but im not 100% sure now. Try without first and if it doesnt save add it on a second try
messages.success(request, f'{user_form.username}, Your profile has been updated!')
return redirect("profile", user_form.username)
В данном примере предполагается, что в остальном форма работает. Если она никогда не работала, то вам придется дважды проверить, что валидация прошла. Если вы не знаете, где искать, Django молча провалит проверку формы.
Я хотел бы ответить на свой собственный вопрос.
Одним из способов было бы обновление модели UserComputedInfo
непосредственно в views.py
.
from django.shortcuts import redirect from django.contrib import messages from .models import UserComputedInfo
def profile(request, username):
if request.method == "POST":
user = request.user
form = UserUpdateForm(request.POST, request.FILES, instance=user)
if form.is_valid():
user_form = form.save()
# How to save post_code to copy_input in UserComputedInfo model
user_computed_info_instance = UserComputedInfo(user_id=user.id)
user_computed_info_instance.copy_input = 1.18 # or whatever value to be assigned
user_computed_info_instance.save()
messages.success(request, f'{user_form.username}, Your profile has been updated!')
return redirect("profile", user_form.username)
return redirect("homepage")
Building on top of your existing answer, the provided answer works for the first time only when user id doesn't exist, You can use Django's get_or_create
Model method, leaving rest of the logics untropched:
def profile(request, username):
if request.method == "POST":
user = request.user
form = UserUpdateForm(request.POST, request.FILES, instance=user)
if form.is_valid():
user_form = form.save()
# How to save post_code to copy_input in UserComputedInfo model
user_computed_info_instance, created =UserComputedInfo.objects.get_or_create(user_id=user.id)
messages.success(request,
f'{user_form.username}, Your profile has been updated!')
user_computed_info_instance.latitude = 1.18
user_computed_info_instance.save()
messages.success(request, f'{user_form.username}, Your profile has been updated!')
return redirect("profile", user_form.username)
return redirect("homepage")