Django 3 Объект «Пользователь» не имеет атрибута «admin» - PullRequest
0 голосов
/ 18 июня 2020

СИТУАЦИЯ

  • Я модифицирую этот GitHub проект из этого YouTube Series и это демонстрация как работает исходное приложение.
  • Моя цель - добавить параметр настроек для учетных записей Продавца (в коде Admin или AdminUser) на торговой площадке, потому что в исходном проекте только покупатели имеют возможность добавлять изображения и их контактные данные.

КОД

model.py

#database table create
class Customer(models.Model):
    #empty fields accept - null=True
    user = models.OneToOneField(User, null=True, blank=True, on_delete=models.CASCADE)
    name = models.CharField(max_length=200, null=True)
    phone = models.CharField(max_length=200, null=True)
    email = models.CharField(max_length=200, null=True)
    profile_pic = models.ImageField(default="profile1.png", null=True, blank=True)
    date_created = models.DateTimeField(auto_now_add=True, null=True)

    #show customer name in admin panel
    def __str__(self):
        return self.name


class Adminuser(models.Model):
    #empty fields accept - null=True
    user = models.OneToOneField(User, null=True, blank=True, on_delete=models.CASCADE)
    name = models.CharField(max_length=200, null=True)
    phone = models.CharField(max_length=200, null=True)
    email = models.CharField(max_length=200, null=True)
    profile_pic = models.ImageField(default="profile1.png", null=True, blank=True)
    date_created = models.DateTimeField(auto_now_add=True, null=True)

    #show customer name in admin panel
    def __str__(self):
        return self.name

url.py

from django.urls import path
from django.contrib.auth import views as auth_views
from . import views

urlpatterns = [
    ...
    path('customer/<str:pk_test>/', views.customer, name="customer"),
    path('adminuser/<str:pk_test>/', views.adminuser, name="adminuser"),
    ...
]

views.py

#CUSTOMER_ONLY PROFILE SETTINGS
@login_required(login_url='login')
@allowed_users(allowed_roles=['customer'])
def accountSettings(request):
    customer = request.user.customer
    form = CustomerForm(instance=customer)
    if request.method == 'POST':
        form = CustomerForm(request.POST, request.FILES,instance=customer)
        if form.is_valid():
            form.save()
    context = {'form':form}
    return render(request, 'accounts/account_settings.html', context)



#ADMIN_ONLY PROFILE SETTINGS
@login_required(login_url='login')
@allowed_users(allowed_roles=['admin'])
def adminSettings(request):
    admin = request.user.admin
    form = AdminForm(instance=admin)
    if request.method == 'POST':
        form = AdminForm(request.POST, request.FILES,instance=admin)
        if form.is_valid():
            form.save()
    context = {'form':form}
    return render(request, 'accounts/account_admin_settings.html', context)

forms.py

from django.forms import ModelForm
from django.contrib.auth.forms import UserCreationForm
from django.contrib.auth.models import User
from django import forms

from .models import *

class CustomerForm(ModelForm):
    class Meta:
        model = Customer
        fields = '__all__'
        exclude = ['user']

class AdminForm(ModelForm):
    class Meta:
        model = Adminuser
        fields = '__all__'
        exclude = ['user']

navbar. html

...
<li class="nav-item">
  <a class="nav-link" href="{% url 'adminsettings' %}">SettingsAdmin</a>
</li>
...

account_admin_settings. html

{%  extends 'accounts/main.html' %}
{% load static %}
{% block content %}

<style>
    .profile-pic{
        max-width: 200px;
        max-height:200px;
        margin: 0 auto;
        border-radius: 50%;
    }
</style>
<!-- -->
<br>
<div class="row">
    <div class="col-md-3">
        <div class="card card-body">
            <a class="btn btn-warning" href="{% url 'dashboard' %}"> &#8592; Back to Profile</a>
            <hr>
            <h3 style="text-align: center">Account Settings</h3>
            <hr>
            <img class="profile-pic" src="{{request.user.customer.profile_pic.url}}" >

        </div>
    </div>
    <div class="col-md-9">
        <div class="card card-body">

            <form method="POST" action="" enctype="multipart/form-data">
                {% csrf_token %}
                {{form.as_p}}

            <input class="btn btn-primary" type="submit" name="Update Information">
            </form>
        </div>
    </div>
</div>

ОШИБКА

AttributeError at /accounts/adminsettings/
'User' object has no attribute 'admin'
Request Method: GET
Request URL:    http://127.0.0.1:8000/accounts/adminsettings/
Django Version: 3.0
Exception Type: AttributeError
Exception Value:    
'User' object has no attribute 'admin'
Exception Location: /Users/computer/ven/lib/python3.7/site-packages/django/utils/functional.py in inner, line 225
Python Executable:  /Users/computer/ven/bin/python3
Python Version: 3.7.3
Python Path:    
['/Users/computer/project',
 '/Users/computer/anaconda3/lib/python37.zip',
 '/Users/computer/anaconda3/lib/python3.7',
 '/Users/computer/anaconda3/lib/python3.7/lib-dynload',
 '/Users/computer/ven/lib/python3.7/site-packages']
Server time:    Wed, 17 Jun 2020 22:17:12 +0000

ИСПЫТАННЫЕ РЕШЕНИЯ

MY FUNCTION ANME  
    try:
        # MY ORIGINAL CODE
    except ObjectDoesNotExist:
        # and what goes here?????
  • @ xyres обновлен view.py def adminSettings (запрос):
#ADMIN_ONLY PROFILE SETTINGS ''' '''
@login_required(login_url='login')
@allowed_users(allowed_roles=['admin'])
def adminSettings(request):
    try:
        admin = requset.user.admin
        form = AdminForm(instance=admin)
        if request.method == 'POST':
            form = AdminForm(request.POST, request.FILES,instance=admin)
            if form.is_valid():
                form.save()
        context = {'form':form}
        return render(request, 'accounts/account_admin_settings.html', context)
    except ObjectDoesNotExist:
        print("Either the entry or blog doesn't exist.")
        return render(request, 'accounts/account_admin_settings.html', context)
  • ОШИБКА: File "/Users/computer/project/accounts/views.py", line 106 form = AdminForm(instance=admin) ^
    • Вернул views.py и models.py обратно в исходное состояние, и теперь я получаю новую ошибку (после изменений миграции makemigration)
NameError at /accounts/adminsettings/
name 'requset' is not defined

1 Ответ

2 голосов
/ 18 июня 2020

Из документации OneToOneField :

Если вы не укажете аргумент related_name для OneToOneField, Django будет использовать имя в нижнем регистре текущей модели в качестве значения по умолчанию.

Итак, вам нужно будет получить доступ к соответствующему экземпляру Adminuser как:

request.user.adminuser

Если вы хотите получить доступ он использует только admin, как указано в документации, вам нужно будет использовать аргумент related_name:

class Adminuser(models.Model):
    user = models.OneToOneField(User, related_name='admin' ...)
    ...

# request.user.admin will work now

Обновление

RelatedObjectDoesNotExist исключение возникает, когда связанный объект не существует в базе данных (это часто бывает, когда связанное поле может быть null). Поскольку на этот раз AttributeError нет, это означает, что Django распознал атрибут admin; Итак, эта проблема исправлена.

Вам придется обрабатывать исключение RelatedObjectDoesNotExist везде, где вы обращаетесь к соответствующему атрибуту.

from django.core.exceptions import ObjectDoesNotExist

try:
    admin = requset.user.admin
except ObjectDoesNotExist:
    admin = # set some other value ...
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...