Django 更新配置文件
Posted
技术标签:
【中文标题】Django 更新配置文件【英文标题】:Django update profile 【发布时间】:2022-01-02 03:18:37 【问题描述】:我有一个关于如何在我的 Django 应用中更新个人资料的问题。
问题是当我填写表格中的空格并单击“保存更改”按钮时,内容不会将管理员中的信息更新到个人资料。
你可以在https://github.com/edisonjao5/Django2App看到它。
或者这是配置文件应用程序中的代码:
models.py
from django.contrib.auth.models import User
from django.db import models
from django.db.models.signals import post_save
from django.dispatch import receiver
from sorl.thumbnail import ImageField
class Profile(models.Model):
user = models.OneToOneField(
User,
on_delete=models.CASCADE,
related_name='profile'
)
SOCIAL = (
('twitter', 'Twitter'),
('facebook', 'Facebook'),
('instagram', 'Instagram'),
('youtube', 'Youtube'),
('github', 'Github'),
)
First_Name = models.CharField(max_length=30)
Last_Name = models.CharField(max_length=30)
Username = models.CharField(max_length=30)
image = ImageField(upload_to='profiles')
Password = models.CharField(max_length=30)
Social = models.CharField(max_length=30, choices=SOCIAL)
def __str__(self):
return self.user.username
@receiver(post_save, sender=User)
def create_user_profile(sender, instance, created, **kwargs):
if created:
Profile.objects.create(user=instance)
@receiver(post_save, sender=User)
def update_user_profile(sender, instance, **kwargs):
instance.profile.save()
views.py
from django.views.generic import DetailView, View, FormView
from django.contrib.auth.mixins import LoginRequiredMixin
from .models import Profile
from .forms import UpdateProfileForm
class UpdateProfileView(LoginRequiredMixin, FormView):
http_method_names =['get', 'post']
template_name = 'profiles/update.html'
form_class = UpdateProfileForm
success_url = '/'
def dispatch(self, request, *args, **kwargs):
self.request = request
return super().dispatch(request, *args, **kwargs)
def get_context_data(self, *args, **kwargs):
context = super().get_context_data(*args, **kwargs)
context["user"] = self.request.user
return context
def form_valid(self, form):
new_object = Profile.objects.update_or_create(
FirstName = form.cleaned_data['First_Name'],
LastName = form.cleaned_data['Last_Name'],
Username = form.cleaned_data['Username'],
Image = form.cleaned_data['image'],
Password = form.cleaned_data['Password'],
)
if form.is_valid():
new_object.save()
return super().form_valid(form)
forms.py
from django import forms
class UpdateProfileForm(forms.Form):
FirstName = forms.CharField(max_length=30)
LastName = forms.CharField(max_length=30)
Username = forms.CharField(max_length=30)
Image = forms.ImageField()
Password = forms.CharField(widget=forms.PasswordInput, min_length=10)
更新.html
% extends "base.html" %
% block title %Update Profile% endblock %
% block body %
<div class="flex justify-center min-h-screen bg-gradient-to-r from-blue-500 to-green-400">
<div class="container sm:mt-12 mt-12 my-auto max-w-md border-2 border-gray-200 p-3 bg-white">
<div class="text-center my-6">
<h1 class="text-3xl font-semibold text-gray-700">Update your Profile</h1>
</div>
<div class="m-6">
<form class="mb-4" method="post" id="profile_form" enctype="multipart/form-data">% csrf_token %
<div class="mb-6">
<label for="id_Firstname" class="block mb-2 text-sm text-gray-600 dark:text-gray-400">First Name</label>
<input type="text" name="Firstname" id="id_Firstname" placeholder="Your first name"
class="w-full px-3 py-2 placeholder-gray-300 border border-gray-300 rounded-md focus:outline-none focus:ring focus:ring-indigo-100 focus:border-indigo-300 dark:bg-gray-700 dark:text-white dark:placeholder-gray-500 dark:border-gray-600 dark:focus:ring-gray-900 dark:focus:border-gray-500"
required />
</div>
<div class="mb-6">
<label for="id_Lastname" class="block mb-2 text-sm text-gray-600 dark:text-gray-400">Last Name</label>
<input type="text" name="Lastname" id="id_Lastname" placeholder="Your last name"
class="w-full px-3 py-2 placeholder-gray-300 border border-gray-300 rounded-md focus:outline-none focus:ring focus:ring-indigo-100 focus:border-indigo-300 dark:bg-gray-700 dark:text-white dark:placeholder-gray-500 dark:border-gray-600 dark:focus:ring-gray-900 dark:focus:border-gray-500"
required />
</div>
<div class="mb-6">
<label for="id_Username" class="block mb-2 text-sm text-gray-600 dark:text-gray-400">Username</label>
<input type="text" name="Username" id="id_Username" placeholder="Your Username"
class="w-full px-3 py-2 placeholder-gray-300 border border-gray-300 rounded-md focus:outline-none focus:ring focus:ring-indigo-100 focus:border-indigo-300 dark:bg-gray-700 dark:text-white dark:placeholder-gray-500 dark:border-gray-600 dark:focus:ring-gray-900 dark:focus:border-gray-500"
required />
</div>
<div class="mb-6">
<label for="id_Image" class="block mb-2 text-sm text-gray-600 dark:text-gray-400">Image</label>
<input type="file" name="Image" id="id_Image"
class="w-full px-3 py-2 placeholder-gray-300 border border-gray-300 rounded-md focus:outline-none focus:ring focus:ring-indigo-100 focus:border-indigo-300 dark:bg-gray-700 dark:text-white dark:placeholder-gray-500 dark:border-gray-600 dark:focus:ring-gray-900 dark:focus:border-gray-500"
/>
</div>
<div class="mb-6">
<div class="flex justify-between mb-2">
<label for="id_Password" class="text-sm text-gray-600 dark:text-gray-400">Password</label>
</div>
<input type="password" name="Password" id="id_Password" placeholder="Your password"
class="w-full px-3 py-2 placeholder-gray-300 border border-gray-300 rounded-md focus:outline-none focus:ring focus:ring-indigo-100 focus:border-indigo-300 dark:bg-gray-700 dark:text-white dark:placeholder-gray-500 dark:border-gray-600 dark:focus:ring-gray-900 dark:focus:border-gray-500"
autocomplete="current-password" required />
</div>
<div class="mb-6">
<div class="flex justify-between mb-2">
<label for="id_Social" class="text-sm text-gray-600 dark:text-gray-400">Social</label>
</div>
<select name="Social" id="id_Social"
class="w-32 px-3 py-2 placeholder-gray-300 border border-indigo-500 rounded-md focus:outline-none focus:ring focus:ring-indigo-100 focus:border-indigo-300 dark:bg-gray-700 dark:text-white dark:placeholder-gray-500 dark:border-gray-600 dark:focus:ring-gray-900 dark:focus:border-gray-500"
required>
<option value=""></option>
<option value="Twitter">Twitter</option>
<option value="Facebook">Facebook</option>
<option value="Instagram">Instagram</option>
<option value="Youtube">Youtube</option>
<option value="Github">Github</option>
</select>
</div>
<div class="mb-6">
<button type="submit"
class="w-full px-3 py-4 text-white bg-indigo-500 rounded-md hover:bg-indigo-600 focus:outline-none duration-100 ease-in-out">Save Changes</button>
</div>
</form>
</div>
</div>
</div>
% endblock %
【问题讨论】:
几个cmets。 1. 我强烈建议不要将密码存储为纯文本 2. 如果此视图仅用于更新,请考虑使用 UpdateView 而不是 FormView docs.djangoproject.com/en/3.2/ref/class-based-views/… 该站点将有助于基于类的视图 - ccbv.co.uk/projects/Django/3.2/django.views.generic.edit/…跨度> 【参考方案1】:在您的 Profile 模型类中,所有字段都是必需的,因为您没有指定 blank=True or null=True
。
在这种情况下,def create_user_profile 信号中的 Profile.objects.create(user=instance) 语句会导致问题,因为只有 user 字段已创建,但其他字段留空。
您应该在 Profile 模型类中的字段上使用 'default' 属性或使用 'blank=True, null=True'。
其次,密码永远不应该存储在个人资料中。这不是 Django 的工作方式。它应该在用户对象中。你可以通过Django documentation了解清楚
我的两分钱是这样的:
class Profile(models.Model):
user = models.OneToOneField(
User,
on_delete=models.CASCADE,
related_name='profile'
)
SOCIAL = (
('twitter', 'Twitter'),
('facebook', 'Facebook'),
('instagram', 'Instagram'),
('youtube', 'Youtube'),
('github', 'Github'),
)
First_Name = models.CharField(max_length=30, blank=True, null=True)
Last_Name = models.CharField(max_length=30, blank=True, null=True)
Username = models.CharField(max_length=30, blank=True, null=True)
image = ImageField(upload_to='profiles', default='profiles/default.jpg')
Social = models.CharField(max_length=30, choices=SOCIAL, blank=True, null=True)
【讨论】:
以上是关于Django 更新配置文件的主要内容,如果未能解决你的问题,请参考以下文章