1

I created signup/login with 'UserCreationForm'. How can I make update possible by using 'UserChangeForm'?

users/models.py

from django.contrib.auth.models
import AbstractUser

# Create your models here.
class CustomUser(AbstractUser): pass
def __str__(self): return self.username

users/forms.py

from django.contrib.auth.forms
import UserCreationForm, UserChangeForm
from.models
import CustomUser

class CustomUserCreationForm(UserCreationForm): class Meta(UserCreationForm): model = CustomUser fields = ('first_name', 'last_name', 'username', 'email')

class CustomUserChangeForm(UserChangeForm): class Meta: model = CustomUser fields = ('first_name', 'last_name', 'username', 'email')

users/views.py

from django.shortcuts import render, redirect

# Create your views here.
from django.urls import reverse_lazy from django.views.generic.edit import CreateView from django.views import View

from .forms import CustomUserCreationForm, CustomUserChangeForm from .models import CustomUser

class SingUpView(CreateView): form_class = CustomUserCreationForm success_url = reverse_lazy('login') template_name = 'signup.html'

#выдает ошибку
class CustomUserUpdateView(View):
def get(self, request, *args, **kwargs):
user_id = kwargs.get("id")
user = CustomUser.objects.get(id=user_id)
form = CustomUserChangeForm(instance=user)
return render(
request, "users/update.html", {"form": form, "user_id": user_id}
)

def post(self, request, *args, **kwargs):
user_id = kwargs.get("id")
user = CustomUser.objects.get(id=user_id)
form = CustomUserChangeForm(request.POST, instance=user)
if form.is_valid():
form.save()
return redirect("users_list")
return render(
request, "users/update.html", {"form": form, "user_id": user_id}
)

I've been trying to create update with inheritance of the View class including 'get/post' methods, but it raises an error

CustomUser matching query does not exist.

users/urls.py

from django.urls import path

from . import views

urlpatterns = [
    path('', views.IndexView.as_view(), name='users_list'),
    path('signup/', views.SingUpView.as_view(), name='signup'),
    path('<int:user_id>/update/', views.CustomUserUpdateView.as_view(), name='users_update'),
]

urls.py

from django.contrib import admin
from django.urls import path, include
from . import views

urlpatterns = [
    path("", views.index, name='home'),
    path("users/", include("task_manager.user.urls")),
    path('users/', include('django.contrib.auth.urls')),
    path('admin/', admin.site.urls),
]

I did everything Google told me to activate get/post (I checked user in the settings, tried to add try/except and use get_user_model), but none of that has worked out.

8
  • in your CustomUserUpdateView you’re trying to fetch a user with an id that doesn’t exist in the database, check your database and tell me if there is data with that id in your query. also add your urls.py Commented Sep 10 at 22:19
  • Can you show your URLs? I agree with @mehdi_ahmadi. It appears you are missing your URL param for the id. I would imagine your url path doesn’t look something like this, which is the cause most likely of your error. path("users/<int:pk>/edit/", CustomUserUpdateView.as_view(), name="user_edit"), Commented Sep 11 at 1:12
  • Changing the logged in user, or any user? Commented Sep 11 at 9:00
  • @mehdi_ahmadi I've checked the db and data with that id exists. I even have a page that displays all the users and it's fine. I'll add my urls.py now, but I have the suitable line there Commented Sep 11 at 20:30
  • 1
    Why your code is so messy. There is no proper indentation in your code. fix it for better understanding. Commented Sep 12 at 15:09

2 Answers 2

1

Use an UpdateView with the request.user as object to update:

from django.views.generic.edit import UpdateView


class CustomUserUpdateView(UpdateView):
    form_class = CustomUserChangeForm
    template_name = 'users/update.html'

    def get_object(self):
        return self.request.user
Sign up to request clarification or add additional context in comments.

3 Comments

if he/she use generic views still have error because in url pattern he/she use user_id instead of pk so you need to add pk_url_kwarg = 'user_id' or change the url pattern
@mehdi_ahmadi: no, because we do not use the pk. The get_object would indeed error if we leave it like this. But here instead of using the pk/..., we just pass self.request.user.
yes i did not notice that
1

the error CustomUser matching query does not exist is not about your view methods its about a mismatch between your URL parameter and how you retrieve the user

in users/urls.py you wrote

path('<int:user_id>/update/', views.CustomUserUpdateView.as_view(), name='users_update'),

you are using <int:user_id> as the URL parameter so in your view instaed of id you should use user_id

your view

user_id = kwargs.get("id")
user = CustomUser.objects.get(id=user_id)

should be like this

user_id = kwargs.get("user_id")  # match the URL parameter
user = CustomUser.objects.get(id=user_id)

or you can just change users/urls.py like this

path('<int:id>/update/', views.CustomUserUpdateView.as_view(), name='users_update'),

also instead of writing get/post manually you can simplify your code by using Django built-in views which is the recommended approach

from django.urls import reverse_lazy
from django.views.generic.edit import UpdateView
from .models import CustomUser
from .forms import CustomUserChangeForm

class CustomUserUpdateView(UpdateView):
    model = CustomUser
    form_class = CustomUserChangeForm
    template_name = 'users/update.html'
    pk_url_kwarg = 'user_id'  # matches <int:user_id> in URL
    success_url = reverse_lazy('users_list')

this way you do not need to handle get and post yourself UpdateView takes care of that for you

note : in this UpdateView example I assumed your URL pattern looks like this

path('<int:user_id>/update/', views.CustomUserUpdateView.as_view(), name='users_update')

that is why the UpdateView I set

pk_url_kwarg = 'user_id'

the default value in Django generic views is pk_url_kwarg = 'pk' so if your url pattern is like this

path('<int:pk>/update/', views.CustomUserUpdateView.as_view(), name='users_update')

you do not need to set pk_url_kwarg

your view would be like this

from django.urls import reverse_lazy
from django.views.generic.edit import UpdateView
from .models import CustomUser
from .forms import CustomUserChangeForm

class CustomUserUpdateView(UpdateView):
    model = CustomUser
    form_class = CustomUserChangeForm
    template_name = 'users/update.html'
    success_url = reverse_lazy('users_list')

2 Comments

yes i finally got it. thank you!
Deliberately using very low quality English in order to avoid the text being detected as having been generated by AI isn't the way to go. Please don't do that. You know perfectly well how to write properly.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.