创建用户配置文件功能时,Django注销功能停止工作

时间:2021-07-13 21:26:44

标签: python django django-models django-views

我正在通过创建一个项目来学习 Django。

我面临的问题是,在我创建另一个函数来查看 view.py 中的用户个人资料后,用户注销功能停止工作。

这是我在 view.py 中的代码

from django.shortcuts import render, redirect
from django.urls import reverse, reverse_lazy
from django.http import HttpResponseRedirect
from django.contrib.auth import login, logout, authenticate
from django.contrib.auth.forms import AuthenticationForm
from django.contrib.auth.decorators import login_required
from django.contrib.auth.models import User
from techuser.models import UserProfile
from techuser.forms import RegistrationForm


# Create your views here.
# Decorator
def login_executed(redirect_to):
"""This Decorator kicks authenticated user out of a view"""

def _method_wrapper(view_method):
    def _arguments_wrapper(request, *args, **kwargs):
        if request.user.is_authenticated:
            return redirect(redirect_to)
        return view_method(request, *args, **kwargs)

    return _arguments_wrapper

return _method_wrapper


@login_executed('tech_blog:index')
def registrationview(request):
    form = RegistrationForm()
    if request.method == 'POST':
        form = RegistrationForm(data=request.POST)
        if form.is_valid():
            user = form.save()
            login(request, user)
            return HttpResponseRedirect(reverse_lazy('tech_blog:index'))
    context = {
        'form': form,
    }
    return render(request, 'registration.html', context)


@login_executed('tech_blog:index')
def loginview(request):
    form = AuthenticationForm()
    if request.method == 'POST':
        form = AuthenticationForm(data=request.POST)
        username, password = request.POST.get('username'), request.POST.get('password')
        
        user = authenticate(username=username, password=password)
        if user:
            if user.is_active:
                login(request, user)
                return HttpResponseRedirect(reverse('tech_blog:index'))
    context = {
        'form': form,
    }
    return render(request, 'login.html', context)

# Logout Function Which I am facing problem
@login_required
def logoutview(request):
    logout(request)
    return HttpResponseRedirect(reverse('tech_blog:index'))

# Logout function is working without this function. But I need this function for showing the user profile
@login_required
def ownprofile(request, user_name):
    user = User.objects.get(username=user_name)

    context = {
        'user': user,
    }
    return render(request, 'author-profile.html', context)

这是来自forms.py

的代码
from django.contrib.auth.forms import UserCreationForm
from django import forms
from django.contrib.auth.models import User


class RegistrationForm(UserCreationForm):
    email = forms.EmailField(required=True, label="Email Address",
                         widget=forms.TextInput(attrs={'placeholder': "example@email.com"}))
    last_name = forms.CharField(required=True, label="Last Name",
                            widget=forms.TextInput(attrs={'placeholder': "Last Name"}))

    class Meta:
        model = User
        fields = ('first_name', 'last_name', 'email', 'username', 'password1', 'password2')
        widgets = {
            'first_name': forms.TextInput(attrs={'placeholder': "First Name"}),
            'username': forms.TextInput(attrs={'placeholder': "username"}),
        }

    def save(self, commit=True):
        user = super(RegistrationForm, self).save(commit=False)
        if commit:
            user.save()
        return user

这是来自models.py

的代码
from django.db import models
from django.contrib.auth.models import User


# Create your models here.
class UserProfile(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE, related_name='user_profile')
    profile_pic = models.ImageField(upload_to='profile_pic', verbose_name="Profile Picture")
    about = models.TextField(verbose_name="About Yourself")
    

    def __str__(self):
        return f'{self.user.first_name} {self.user.last_name}\'s About'

这是来自url.py

的代码
from django.urls import path
from techuser import views

app_name = "tech_user"

urlpatterns = [
    path('<user_name>/', views.ownprofile, name='ownprofile'),
    path('registration/', views.registrationview, name='registration'),
    path('login/', views.loginview, name='login'),
    path('logouturl/', views.logoutview, name='logouturl'),
]

这是来自 HTML 文件的 URL 调用

<ul>
    <li><a href="{% url "tech_user:ownprofile" user_name=user.username %}"><i class="fal fa-user-alt"></i> Profile</a></li>
    <li><a href="{% url "tech_user:logouturl" %}"><i class="fal fa-sign-out-alt"></i> Logout</a></li>
</ul>

这是我在从 HTML 页面调用注销时在浏览器中的 复制粘贴视图 中遇到的错误(如果我在 ownprofile 中有 views.py 函数) :

Environment:


Request Method: GET
Request URL: http://127.0.0.1:8000/account/logouturl/

Django Version: 3.2
Python Version: 3.9.2
Installed Applications:
['django.contrib.admin',
 'django.contrib.auth',
 'django.contrib.contenttypes',
 'django.contrib.sessions',
 'django.contrib.messages',
 'django.contrib.staticfiles',
 'techblog',
 'techuser',
 'crispy_forms']
Installed Middleware:
['django.middleware.security.SecurityMiddleware',
 'django.contrib.sessions.middleware.SessionMiddleware',
 'django.middleware.common.CommonMiddleware',
 'django.middleware.csrf.CsrfViewMiddleware',
 'django.contrib.auth.middleware.AuthenticationMiddleware',
 'django.contrib.messages.middleware.MessageMiddleware',
 'django.middleware.clickjacking.XFrameOptionsMiddleware']



Traceback (most recent call last):
  File "C:\Users\Hridoy\AppData\Local\Programs\Python\Python39\lib\site-packages\django\core\handlers\exception.py", line 47, in inner
    response = get_response(request)
  File "C:\Users\Hridoy\AppData\Local\Programs\Python\Python39\lib\site-packages\django\core\handlers\base.py", line 181, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "C:\Users\Hridoy\AppData\Local\Programs\Python\Python39\lib\site-packages\django\contrib\auth\decorators.py", line 21, in _wrapped_view
    return view_func(request, *args, **kwargs)
  File "F:\Bohubrihi\Courses\Bohubrihi Full Stack Web Development\05. Django Backend\Assignments\1\techbangla\techuser\views.py", line 189, in ownprofile
    user = User.objects.get(username=user_name)
  File "C:\Users\Hridoy\AppData\Local\Programs\Python\Python39\lib\site-packages\django\db\models\manager.py", line 85, in manager_method
    return getattr(self.get_queryset(), name)(*args, **kwargs)
  File "C:\Users\Hridoy\AppData\Local\Programs\Python\Python39\lib\site-packages\django\db\models\query.py", line 435, in get
    raise self.model.DoesNotExist(

Exception Type: DoesNotExist at /account/logouturl/
Exception Value: User matching query does not exist.

这是我在浏览器的交互式视图中遇到的错误之一: enter image description here

我已经在这个问题上花了很多天,但仍然无法解决这个问题。谁能帮我解决这个问题?为什么我收到错误消息?

1 个答案:

答案 0 :(得分:0)

您可以尝试将模板中的 Logout 函数设为 form,即:

template.html

<form action="{% url 'tech_user:logouturl' %}" method='POST'>
    {% csrf_token %}
    <button type="submit">Log out</button>
</form>

然后在您的 views.py

中定义注销的函数中
def logoutview(request, *args, **kwargs):
    if request.method == 'POST':
        logout(request)
        return HttpResponseRedirect(reverse('tech_blog:index'))

同样在 yoyr urls.py 中你不能只写 <user_name>,当你使用 <> 时你需要指定你要传递的类型,所以在这种情况下:

from django.urls import path
from techuser import views

app_name = "tech_user"

urlpatterns = [
    path('<str:user_name>/', views.ownprofile, name='ownprofile'),
    path('registration/', views.registrationview, name='registration'),
    path('login/', views.loginview, name='login'),
    path('logouturl/', views.logoutview, name='logouturl'),
]

我希望这些更改可以解决您的问题

相关问题