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 更新配置文件的主要内容,如果未能解决你的问题,请参考以下文章

Django实现自动发布(4配置文件管理)

Django 编辑用户配置文件

django中使用FastDFS分布式文件系统接口代码实现文件上传下载更新删除

在 Django 中编辑用户配置文件时检查重复的电子邮件

在一个请求中更新用户配置文件和用户

Django的配置与了解