Как мне обновить значение CustomUser через UpdateView, используя скрытую логику

#django #django-views #django-forms

#django #django-просмотры #django-forms

Вопрос:

Я потратил на это несколько часов, и я не вижу никаких признаков того, почему изменение флага не проходит. Пожалуйста, обратите внимание, что форма изменения уже работает для всех открытых полей, т. Е. Пользователь может войти и уже изменить имя или страну, и оно будет сохранено после нажатия на обновить профиль. Что я сейчас пытаюсь сделать, так это также изменить флаг confirmed_email на True (но не сообщая и не позволяя пользователю видеть его) всякий раз, когда клиент вносит обновление в форму. Для этого я проверяю, был ли пользователь зарегистрирован с помощью Linkedin (или любой социальной учетной записи, если на то пошло) с помощью чего-то вроде «if user.social_auth.exists()»». Тем не менее, дело не в том, что я не могу выполнить эту функцию, а в том, что даже когда я использую глупое условие, о котором я знаю, что оно верно, поле «email_confirmed» все равно НЕ изменится на True в фоновом режиме.

Заранее большое спасибо. Я ценю ваше время. PS. Я новичок в Django, но мне это нравится.

Models.py

 
    class CustomUser(AbstractUser):
            id = models.BigAutoField(primary_key=True)
            email = models.EmailField(unique=True)
            email_confirmed = models.BooleanField(default=False)
            country = models.CharField(max_length=30,choices=COUNTRY, null=True, blank=False)
            first_name = models.CharField(max_length=50, null=False, blank=False, default="")
            last_name = models.CharField(max_length=50, null=False, blank=False, default="")

 

Views.py

 
    class SignUpView(CreateView):
        form_class = CustomUserCreationForm
        success_url = reverse_lazy('home')
        template_name = 'signup.html'
        ...
    
    class UpdateProfileView(UpdateView): 
        form_class = CustomUserChangeForm
        success_url = reverse_lazy('home')
        template_name = 'update_profile.html'
        def get_object(self, queryset=None):
          return self.request.user

 

Forms.py

 
    from django import forms
    from django.contrib.auth.forms import UserCreationForm, UserChangeForm
    from .models import CustomUser
    
    class CustomUserCreationForm(UserCreationForm):
        class Meta(UserCreationForm.Meta):
            model = CustomUser
            fields = ('first_name', 'last_name','country',) 
    
    class CustomUserChangeForm(UserChangeForm):
        password = None
        class Meta:
            model = CustomUser
            fields = ('first_name', 'last_name','country',)

update_profile.html
 
 {% extends 'base.html' %}
{% load crispy_forms_tags %}
{% block title %}Home{% endblock title %}

{% block content %}
{% if user.is_authenticated %}
  <h2>Update Profile</h2>
  <form method="post">
    {% csrf_token %}
    {{ form|crispy }}
    <button class="btn btn-success" type="submit">Update</button>
  </form>
{% else %}
  <p>You are not logged in</p>
  <a href="{% url 'login' %}">Log In</a> |
  <a href="{% url 'signup' %}">Sign Up</a>
{% endif %}
{% endblock content %}
 
 

My main attempt was to adding another leg in the view (see def ChangeActiveStatus below).
 
 class UpdateProfileView(UpdateView): 
    form_class = CustomUserChangeForm
    success_url = reverse_lazy('home')
    template_name = 'update_profile.html'
    def get_object(self, queryset=None):
      return self.request.user
    def ChangeActiveStatus(request):
      if request.method == "POST":
        form = self.form_class(request.POST)
        user = form.save(commit=False)
        if form.is_valid() and user.social_auth.exists() == True:
          user.email_confirmed = True
          form.save()
        else:
          form = form()
      return render(request, 'login', {'form':form}) 
 

Ответ №1:

Проблема здесь в том, что вы устанавливаете email_confirmed = True on user и not form.instance . Вы также можете сохранить user экземпляр, а не вызывать form.save() .

   form = self.form_class()
  if request.method == "POST":
    form = self.form_class(request.POST)
    if form.is_valid() and user.social_auth.exists():
      user = form.save(commit=False)
      user.email_confirmed = True
      user.save()
  return render(request, 'login', {'form':form}) 
 

Или

   form = self.form_class()
  if request.method == "POST":
    form = self.form_class(request.POST)
    if form.is_valid() and user.social_auth.exists():
      form.instance.email_confirmed = True
      form.save()
  return render(request, 'login', {'form':form}) 
 

Комментарии:

1. Спасибо @schillingt за то, что нашли время ответить. К сожалению, я безуспешно пробовал оба ваших предложения. Я даже не вижу никаких ошибок в консоли, она просто не обновляется. Я также протестировал более простое условие (например, проверку правильности формы), и оно также не сработало. Ниже то, что я использовал: просто чтобы убедиться, что вы советовали включить свой код прямо под 'def ChangeActiveStatus (запрос):' правильно?

Ответ №2:

В итоге я реализовал решение с помощью моделей.вместо этого py, в основном обходя необходимость сохранения любых изменений в одном из полей через представления, т. Е. Это логика, которая будет срабатывать каждый раз, когда клиент что-то меняет в своем профиле.

 
        def save(self, *args, **kwargs):
            try:
                CustomUser.objects.latest('id').id   
            except:
            ...
            ...


                if self.is_active == True and self.email_verified == False:
                    self.email_verified = True
                super(CustomUser, self).save(*args, **kwargs)
        def __str__(self):
            return self.email