Reputation: 3076
SITUATION
CODE
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' %}"> ← 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>
ERROR
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
TRIED SOLUTIONS
@allowed_users(allowed_roles=['customer'])
change to @allowed_users(allowed_roles=['customer','admin'])
to have everything in to 1 function in def accountSettings(request):
gives erroruser = models.OneToOneField(User, null=True, blank=True, on_delete=models.CASCADE, related_name='admin')
RelatedObjectDoesNotExist at /accounts/adminsettings/ User has no admin.
request.user.adminuser
to the view function
AttributeError at /accounts/adminsettings/ 'User' object has no attribute 'adminuser'
MY FUNCTION ANME
try:
# MY ORIGINAL CODE
except ObjectDoesNotExist:
# and what goes here?????
#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)
^
NameError at /accounts/adminsettings/
name 'requset' is not defined
Upvotes: 1
Views: 2593
Reputation: 21734
From OneToOneField
's documentation:
If you do not specify the
related_name
argument for theOneToOneField
, Django will use the lowercase name of the current model as default value.
So, you'll have to access the related Adminuser
instance as:
request.user.adminuser
If you want to access it using just admin
, as mentioned in the docs, you'll have to make use of the related_name
argument:
class Adminuser(models.Model):
user = models.OneToOneField(User, related_name='admin' ...)
...
# request.user.admin will work now
RelatedObjectDoesNotExist
exception is raised when the related object doesn't exist in the database (this is often the case when related field can be null
). Since there's no AttributeError
this time, that means Django did recognise the admin
attribute; so, that issue is fixed.
You'll have to handle RelatedObjectDoesNotExist
exception everywhere you're accessing the related attribute.
from django.core.exceptions import ObjectDoesNotExist
try:
admin = requset.user.admin
except ObjectDoesNotExist:
admin = # set some other value ...
Upvotes: 3