【问题标题】:Django - User created but Profile is missingDjango - 用户创建但配置文件丢失
【发布时间】:2020-09-02 12:59:18
【问题描述】:

当我注册一个新用户时,我可以从管理页面看到该用户已创建。 但是每当我在导航栏中进入我的个人资料页面时,我都会收到以下错误。

在我在我的个人资料页面上添加一个功能(删除用户和个人资料的按钮)之前它实际上是有效的,但我看不到我需要页面来修复这个错误。

profile.html

{% extends "digitalFarm/base.html" %}
{% load crispy_forms_tags %}

{% block content %}
      <div class="content-section">
             <div class="media">
                    <img class="rounded-circle account-img" src="{{ user.profile.image.url }}">
                    <div class="media-body">
                           <h2 class="account-heading">{{ user.username }}</h2>
                           <p class="text-secondary">{{ user.email }}</p>
                    </div>
             </div>
          <form method="POST" enctype="multipart/form-data">
              {% csrf_token %}
              <fieldset class="form-group">
                  <legend class="boder-bottom mb-4">Profile info</legend>
                  {{ u_form|crispy }}
                  {{ p_form|crispy }}
                  {{ d_form|crispy }}
              </fieldset>
              <div class="form-group">
                  <button class="btn btn-outline-info" type="submit">Update Profile</button>
              </div>
          </form>

          <form>
              {% csrf_token %}
              <fieldset class="form-group">
                  <legend class="border-bottom mb-4">Delete User Account</legend>
              </fieldset>
              <div class="form-group">
                  <button class="btn btn-danger">
                      <a style="color: white" href="{% url 'profile_confirm_delete' %}">Delete Account</a></button>
              </div>
          </form>
      </div>
{% endblock content %}

views.py

    def register(request):
    if request.method == 'POST':
        form = UserRegisterForm(request.POST)
        if form.is_valid():
            form.save()
            username = form.cleaned_data.get('username')
            messages.success(request, f'Your account has been created! You are now able to login')
            return redirect('login')
    else:
        form = UserRegisterForm()
    return render(request, 'users/register.html', {'form': form})

def profile_confirm_delete(request):
    user = request.user
    context = {
        'user': user
    }
    return render(request, 'users/profile_confirm_delete.html', context)

@login_required
def profile(request):
    if request.method == 'DELETE':
        print('delete works')
        return redirect('digitalFarm-home')

    if request.method == 'POST':
        u_form = UserUpdateForm(request.POST, instance=request.user)
        p_form = ProfileUpdateForm(request.POST, request.FILES, instance=request.user.profile)

        if u_form.is_valid() and p_form. is_valid():
            u_form.save()
            p_form.save()
            messages.success(request, f'Your account has been updated!')
            return redirect('profile')
    else :
        u_form = UserUpdateForm(instance=request.user)
        p_form = ProfileUpdateForm(instance=request.user.profile)

    context = {
        'u_form' : u_form,
        'p_form' : p_form
    }
    return render(request, 'users/profile.html', context)

信号.py

@receiver(post_save, sender=User)
def create_profile(sender, instance, created, **kwargs):
    print("INSIDE CREATE_PROFILE")#negative
    if created:
        print("INSIDE CREATED_PROFILE")#negative
        Profile.objects.create(user=instance)

@receiver(post_save, sender=User)
def save_profile(sender, instance, **kwargs): #kwargs= accepts any additional keywords
        instance.profile.save()

@receiver(pre_delete, sender=User)
def delete_profile(sender, instance, **kwargs): #kwargs= accepts any additional keywords
        instance.profile.delete()

forms.py

class UserRegisterForm(UserCreationForm):
    email = forms.EmailField()

    class Meta:
        model = User
        fields = ['username', 'email', 'password1', 'password2']

#Update
class UserUpdateForm(forms.ModelForm):
    email = forms.EmailField()

    class Meta:
        model = User
        fields = ['username', 'email']

class ProfileUpdateForm(forms.ModelForm):
    print("INSIDE ProfileUpdateForm")
    class Meta:
        model = Profile
        fields = ['image']

#Delete
class ProfileDeleteForm(forms.ModelForm):
    class Meta:
        model = Profile
        fields = ['image']

class UserDeleteForm(forms.ModelForm):
    class Meta:
        model = User
        fields = []   #Form has only submit button.  Empty "fields" list still necessary, though.

【问题讨论】:

  • 我没有看到 d_form ({{ d_form|crispy }}) 在您的 profile 视图中的任何位置声明。这是从哪里来的?
  • 我也注意到了,所以我最近删除了它。它应该用于删除配置文件。我想也许我会创建但也会在之后立即删除它。但即使我删除了 d_ 表单,配置文件仍然丢失。

标签: python django user-profile


【解决方案1】:

在您的信号.py 中,我没有看到任何 save() 指令,您的配置文件实例应该如何进入数据库,数据库配置文件表是空的。你需要这样的东西(用于创建):

Profile.objects.create(user=instance).save()

实际上

profileInstance = Profile.objects.create(user=instance)
profileInstance.initNewProfile() # setup context default values
profileInstance.save()

此外,在删除时,实际上有更好的选项来删除依赖实例:ORM 级别的 CASCADE。必须在类(models.py)中定义

【讨论】:

  • docs.djangoproject.com/en/3.0/ref/models/querysets/#create 记录了.objects.create 是包括.save 方法的快捷方式。您不需要在.create 之后手动调用.save
  • 这是个好主意!我尝试了两种方法,但不幸的是它没有奏效......但我也假设信号中的 create_profile 方法甚至不会输入,因为我的终端没有打印出任何东西
  • (1) 必须打印 degug 注释,否则不会触发
  • 如果你删除了一个实例,你必须在某个地方创建一个明确的新实例。它在哪里。您的用户创建事件仅在创建新用户时触发一次。您的 instance.profile.save(),如果配置文件被删除,则没有要保存的实例。
  • 但我创建用户时甚至没有创建配置文件。我没有删除任何个人资料。但是每当我登录并单击我的个人资料页面时,我都会收到此错误。
猜你喜欢
  • 1970-01-01
  • 2012-07-14
  • 1970-01-01
  • 2019-05-23
  • 2020-07-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多