Django - User, UserProfile, and Admin - python

I'm trying to get the Django Admin interface to display information about my profile. It displays all of my users but no profile information. I'm not quite sure how to get it to work.
I found this code after a quick google search:
from auth.models import UserProfile
from django.contrib import admin
from django.contrib.auth.models import User
from django.contrib.auth.admin import UserAdmin
admin.site.unregister(User)
class UserProfileInline(admin.StackedInline):
model = UserProfile
class UserProfileAdmin(UserAdmin):
inlines = [UserProfileInline]
admin.site.register(User, UserProfileAdmin)
However, I don't think that it worked. When I log into the admin page, I see Users, Groups, and Sites. I click Users and I see a list of all of my Users, but no indication of any profile. Clicking on a user shows me info about that user, but still no profile information.
If it will help, here is my model declaration:
from django.db import models
from django.contrib.auth.models import User
class UserProfile(models.Model):
company = models.CharField(max_length=30)
user = models.ForeignKey(User, unique=True)
And my registration code:
def register(request):
if request.method == 'POST':
uf = UserForm(request.POST)
upf = UserProfileForm(request.POST)
if uf.is_valid() and upf.is_valid():
user = uf.save()
userprofile = upf.save(commit=False)#need to get the user profile object first
userprofile.user = user #then set the user to user
userprofile.save() #then save to the database
return HttpResponseRedirect('/auth/login/')
else:
uf = UserForm()
upf = UserProfileForm()
return render_to_response('register.html', dict(userform=uf,userprofileform=upf),context_instance=RequestContext(request))

I can't see exactly what's wrong, but here's a slightly simpler example that I know works. Put this is any working admin.py. Try adding a trailing comma to your inline-- some things break without it.
from django.contrib import admin
from django.contrib.auth.models import User
from django.contrib.auth.admin import UserAdmin
from accounts.models import UserProfile
admin.site.unregister(User)
class UserProfileInline(admin.StackedInline):
model = UserProfile
class UserProfileAdmin(UserAdmin):
inlines = [ UserProfileInline, ]
admin.site.register(User, UserProfileAdmin)

This is not exactly an answer to your question BUT, according to Django Admin documentation, you can display information from UserProfile in your User "table". And you can make it searchable.
That would look something like this (modifying answer from C. Alan Zoppa):
class UserProfileAdmin(UserAdmin):
inlines = [ UserProfileInline, ]
def company(self, obj):
try:
return obj.get_profile().company
except UserProfile.DoesNotExist:
return ''
list_display = UserAdmin.list_display + ('company',)
search_fields = UserAdmin.search_fields + ('userprofile__company',)
You might have an issue though with search if your profile class is no longer called UserProfile.

The missing comma shouldn't matter. I suspect the problem is that you added a new admin.py but the development server didn't recognize it. If you restart the development server, it'll see the new file.

Related

How to save data from the User form that is implemented by built-in auth. User using UserCreationForm in Django?

Hi I am new to Django and I have created a login/logout model Django inbuilt User and UserCreationForm. It is working fine but my issue is I have define two custom inputs in my form and it is displaying on the web page when I run the server but when I check the user under the admin, I only see the details of User defined fields not my custom fields.
How to save it's data to my User model?
or maybe If I defined the custom fields wrong how do I change it so that I can save it's data in my model.
My custom defined fields that is address and phone number is not showing in Admin User and it's data is not getting saved.
model.py
from django.db import models
from django.contrib import auth
# Create your models here.
class User(auth.models.User,auth.models.PermissionsMixin):
def __str__(self):
return "#{}".format(self.username)
forms.py
from django.contrib.auth import get_user_model
from django.contrib.auth.forms import UserCreationForm
from django import forms
class UserCreateform(UserCreationForm):
address = forms.CharField(max_length=150, required=True)
phone_number = forms.IntegerField(required=True)
class Meta(UserCreationForm.Meta):
model = get_user_model()
fields = ('username','email','password1','password2')
def __init__(self,*args,**kwargs):
super().__init__(*args,**kwargs)
self.fields['username'].label = 'Display Name'
views.py
from django.shortcuts import render
from django.urls import reverse_lazy
from django.views.generic import CreateView
from . import forms
# Create your views here.
class SignUp(CreateView):
form_class = forms.UserCreateform
success_url = reverse_lazy('login')
template_name = 'account/signup.html'
Adding fields to a ModelForm doesn't do anything in terms of saving them, if they are not fields of the Model. So of course, address and phone_number aren't saved, your User model doesn't have those fields.
You need to have a Model to save those fields. As explained here, you have two options:
Create a Profile model to save all extra fields
Create a custom User model, subclassing AbstractUser or AbstractBaseUser.
My advice: Do both. Save your extra fields in a Profile model.
And subclass AbstractUser, so you have the option to add useful methods and properties to the User model (right now, just __str__()).
Why not just subclass? Because as your app grows, you'll want to add more an more things to a user's profile. Maybe you want to create different types of profiles, e.g. the private profile and the professional profile. The User itself should be compact, just managing authentication and permissions.
Note: your current User model is wrong. You must not subclass auth.User but auth.AbstractUser.

Issue while adding inline user profile form with Django admin user form

I got stuck with small issue in django project, I hope I can get some good answers here.
I have added user profile inline form with django User form by doing code like this:
from django.core.exceptions import ValidationError
from django.contrib import admin
from django.contrib.auth.admin import UserAdmin
from django.contrib.auth.forms import UserChangeForm, UserCreationForm
from django.contrib.auth.models import User
from djangocalendar.models import UserProfile
from tableapp.models import *
from djangocalendar.models import *
from django import forms
class UserProfileInline(admin.StackedInline):
model = UserProfile
can_delete = True
verbose_name_plural = 'profile'
class MyUserChangeForm(UserChangeForm):
def clean_first_name(self):
if self.cleaned_data["first_name"].strip() == '':
raise ValidationError("First name is required.")
return self.cleaned_data["first_name"]
def clean_last_name(self):
if self.cleaned_data["last_name"].strip() == '':
raise ValidationError("Last name is required.")
return self.cleaned_data["last_name"]
# Define a new User admin
class MyUserAdmin(UserAdmin):
form = MyUserChangeForm
inlines = UserProfileInline,
# Register your models here
admin.site.unregister(User)
admin.site.register(User, MyUserAdmin)
Issue I am facing with this, This inline appears with User Add form and with Change user form too. I don't want it to display while adding user.
Like In this screenshot: Inline form appears with add User form! I don't want this to add inline form here. But I want to display inline form while editing user with other forms like personal form, information form.
I have found solution
Define a new User admin
class MyUserAdmin(UserAdmin):
form = MyUserChangeForm
inlines = UserProfileInline,
def get_inline_instances(self, request, obj=None):
if not obj:
return list()
return super(MyUserAdmin, self).get_inline_instances(request, obj)

In Django admin, can I prevent added user profile fields from appearing on "Add user" page?

I created a profile model that contains additional fields for the User model. It works as expected, but when I add a new user, the added fields appear on both the "Add user" page (first page) and the "Change user" page (second page). How can I prevent my added fields from appearing on the "Add user" page?
models.py
from django.db import models
from django.contrib.auth.models import User
class Member(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
my_added_field = models.CharField(max_length=15)
admin.py
from django.contrib import admin
from django.contrib.auth.admin import UserAdmin
from django.contrib.auth.models import User
from .models import Member
class MemberInline(admin.StackedInline):
model = Member
class MemberAdmin(UserAdmin):
inlines = (MemberInline,)
admin.site.unregister(User)
admin.site.register(User, MemberAdmin)
You need to use exclude = 'your-field-name' in Meta 'your-field-name' is field which you not want to show in admin section.

Django: OneToOneField has no attribute model

I am trying to create profile system where my users django username will be their username on the site, and also allow them to create a bio. However when I try to migrate, I get this error:
AttributeError: 'OneToOneField' object has no attribute 'model'
Here is my models.py files:
from django.db import models
from django.contrib.auth.models import User
class UserProfile(models.Model):
user = models.OneToOneField(User, unique=True)
bio = models.TextField(null=True)
slug = models.SlugField(default=user)
def __unicode__(self):
return "%s's profile" % self.user
def create_profile(sender, instance, created, **kwargs):
if created:
profile, created = UserProfile.objects.get_or_create(user=instance)
# Signal while saving user
from django.db.models.signals import post_save
post_save.connect(create_profile, sender=User)
And here is my admin.py:
from django.contrib import admin
from profiles.models import UserProfile
class UserProfileAdmin(admin.ModelAdmin):
list_display = ["user"]
admin.site.register(UserProfile, UserProfileAdmin)
Anyone know what the problem is? Thanks.
Try without importing the User model from django.contrib.auth.
Remove (or comment out) the User import line, the signal binding, and switch to string based model specification of relation in OneToOneField. The example of string based relation specification can be found in the docs.
This looks like a circular dependency thing.
If you'd still get an error, try to remove stuff you don't need from INSTALLED_APPS.

Django admin panel doesn't work after modify default user model

I was trying to extend user profile. I founded a few solutions, but the most recommended was to create new user class containing foreign key to original django.contrib.auth.models.User class. I did it with this so i have in models.py:
class UserProfile(models.Model):
user = models.ForeignKey(User, unique=True)
website_url = models.URLField(verify_exists=False)
and in my admin.py
from django.contrib import admin
from someapp.models import *
from django.contrib.auth.admin import UserAdmin
# Define an inline admin descriptor for UserProfile model
class UserProfileInline(admin.TabularInline):
model = UserProfile
fk_name = 'user'
max_num = 1
# Define a new UserAdmin class
class MyUserAdmin(UserAdmin):
inlines = [UserProfileInline, ]
# Re-register UserAdmin
admin.site.unregister(User)
admin.site.register(User, MyUserAdmin)
And now when I'm trying to create/edit user in admin panel i have an error:
"Unknown column 'content_userprofile.id' in 'field list'" where content is my appname.
I was trying to add line AUTH_PROFILE_MODULE = 'content.UserProfile' to my settings.py but with no effect.
How to tell panel admin to know how to correctly display fields in user form?
After some effort I found working solution:
the AUTH_PROFILE_MODULE = 'content.UserProfile' is required
please drop your database (auth_user, yourapp_userprofile tables should be enough)
finally python manage.py syncdb

Categories

Resources