Where do I create custom profile models for django-userena? - python

I have a django app called my_app that uses django-userena; I am trying to create and use my own profile model by following the django-userena installation documentation.
In my_app/models.py I've added
from django.contrib.auth.models import User
from django.utils.translation import ugettext as _
from userena.models import UserenaBaseProfile
class MyProfile(UserenaBaseProfile):
user = models.OneToOneField(User,
unique=True,
verbose_name=_('user'),
related_name='my_profile')
favourite_snack = models.CharField(_('favourite snack'),
max_length=5)
And then I've modified my_app/settings.py to include AUTH_PROFILE_MODULE = 'my_app.MyProfile' .
And yet, when I try to view any web page from my_app I get a SiteProfileNotAvailable. This error goes away if I move MyProfile to accounts/models.py
It seems like a bad idea to modify the accounts app in order to add custom fields. Am I wrong? Is there a way to add a custom profile module without modifying accounts/models.py?

I had the same issue. For me it happened because I forgot to put my_app (or accounts as in the official docs) into INSTALLED_APPS.

Related

Extending user models in Django saves password publicly

The password for newly created users is shown publicly on the admin console models. Why is that and how I do it correctly?
Furthermore, I am not actually able to login with any of the new users created in the Accounts_app. I am able to login only with the python manage.py createsuperuser
I created at the early point in the project.
Here is the models.py
from django.contrib.auth.models import AbstractUser
class ProjectUser(AbstractUser):
def __str__(self):
return self.username
Here is the settings.py
PASSWORD_HASHERS = [
'django.contrib.auth.hashers.Argon2PasswordHasher',
'django.contrib.auth.hashers.BCryptSHA256PasswordHasher',
'django.contrib.auth.hashers.BCryptPasswordHasher',
'django.contrib.auth.hashers.PBKDF2PasswordHasher',
'django.contrib.auth.hashers.PBKDF2SHA1PasswordHasher',
]
AUTH_USER_MODEL = 'accounts_app.ProjectUser'
Here is my admin view
To create the user, I click "Add User" in the app admin view.
Here is the apps.py file
from django.apps import AppConfig
class AccountsConfig(AppConfig):
name = 'accounts_app'
Here is the admin.py file
from django.contrib import admin
from accounts_app.models import ProjectUser
# Register your models here.
admin.site.register(ProjectUser)
Although you set ProjectUser to be the AUTH_USER_MODEL, you registered it in the admin as a standard model, not the user one. You need to use the user admin, as shown in the docs, since this takes care of hashing the password:
from django.contrib.auth.admin import UserAdmin
admin.site.register(ProjectUser, UserAdmin)
You'll need to delete and recreate the users you generated via the admin before changing this.
Firstable, what do you want to do, extend or custom the User Model?
If you want to extend... It's enough with a foreign key. For this, the Django project recommends using OneToOneField(User)
In this case, see the link below.
https://docs.djangoproject.com/en/2.1/topics/auth/customizing/#extending-the-existing-user-model
In the other hand, if you want to custom the User model, you must have to do this before doing the migrations. The initial setup must have your customization. You can create an app only for the User Model customization.
In this case, see the links below.
https://docs.djangoproject.com/en/2.1/topics/auth/customizing/#substituting-a-custom-user-model
https://wsvincent.com/django-tips-custom-user-model/
I hope this helped you

How to clear cache from django database in version 2.1?

I am facing weird issue, after wasting so much time I found out that this is the problem because of Database cache.
I made a Model Name "Profile" later flushdb / deleted it.
After few hours I made it again but getting this error
"No such column"
then I removed all sql3db files *.pyc file etc,
& run my model again (so django will recreate db structure {also performed migrate & makemigrations}).
But still same error,
then I just renamed my db & the same code working now fine.
My problem is I have to use that old Old Model name again
but not able to get because of db cache (or maybe something)
please guide me.
admin.py
from django.contrib import admin
from django.contrib.auth.models import User
from .models import Profiles
admin.site.register(Profiles)
my model:
from django.contrib.auth.models import User
from django.db import models
class Profiles(models.Model):
# p2= models.CharField(max_length=14)
phone = models.CharField(max_length=14)
city = models.CharField(max_length=20)
province = models.CharField(max_length=20)
username2 = models.ForeignKey(User, on_delete=models.CASCADE)
Note: I have tried all old solution available on this web,
but in my case not working.
Please check this django documentation link,it will surly helps you.
https://docs.djangoproject.com/en/2.1/topics/cache/
here are the basic related queries,it may helpful for understanding.
# You can delete keys explicitly with delete(). This is an easy way of clearing the
#cache for a particular object:
#cache.delete(key, version=None)
#cache.delete_many(['a', 'b', 'c'])
#cache.clear()

Do you and should you rename a custom User model in Django 1.9?

I am creating a new User model for my Django project. I have been many people calling their custom user model, XXXUser and custom user manager, XXXUserManager.
I was wondering if there is a reason for this. Can you just create a custom user and still call it User? Does this create conflicts in the code?
Basically you can. But for readability purposes it's better to do it XxxUser, if you see XxxUser you are instantly understand that this is custom one. And you need to keep in mind that you should replace some code that is common for base usage.
Such as(should be replaces)
from django.contrib.auth.models import User
Should be
from django.contrib.auth import get_user_model
User = get_user_model()
And if you reference to User model in your models.py you need to
from django.conf import settings
class SomeModel(models.Model):
field = models.RetationField(settings.AUTH_USER_MODEL)
Also do not forget to set your settings.AUTH_USER_MODEL that references to your custom one
If you want custom user models then take a look at subclassing either AbstractUser or AbstractBaseUser detailed in the documentation here https://docs.djangoproject.com/en/1.10/topics/auth/customizing/#extending-django-s-default-user
You can then do something like the following:
from django.contrib.auth.models import AbstractUser
from django.db import models
from django.utils.translation import ugettext_lazy as _
class KarmaUser(AbstractUser):
karma = models.PositiveIntegerField(verbose_name=_("karma"), default=0, blank=True)
# Inside project/settings.py
AUTH_USER_MODEL = "profiles.KarmaUser"
You could also create your own completely seperate model and tie it back to the user with a one-to-one relationship

How to add a Model (not an app) to django?

I am using django 1.3 and just trying to add a simple model(not an app) to the admin site.
so i have tried:
from django.db import models
class UserProfile(models.Model):
notes = models.TextField(db_name="Notes", max_length=15)
def _str_(self):
return self.notes
class Admin:
pass
and have also tried creating the admin.py file in the site root and in the /static/admin/ directory and have attempted two standard entries for it as follows:
from django.contrib import admin
from mock.models import UserProfile
admin.site.register(UserProfile)
and
from django.contrib import admin
from mock.models import UserProfile
class UserProfileAdmin(admin.ModelAdmin):
pass
admin.site.register(UserProfile, UserProfileAdmin)
any help would be much appreciated. Thank you very much.
Don't define your Admin class in the model itself like below. That's the really old way to do it, from before Django 1.0. I'm not sure what tutorial or documentation you are using, but it's very out of date.
class UserProfile(models.Model):
notes = models.TextField(db_name="Notes", max_length=15)
# don't do this!
class Admin:
pass
Defining a UserProfileAdmin is the correct approach. The admin.py file should not go in the /static/admin/. The static directory is for static files like CSS stylesheets and javascript files, not for Django code.
As for your question of whether you can define a model without defining an app, it's not a really good idea. Lots of parts of django assume that each model belongs to an app. For example the database table name is appname_modelname.
Creating an app doesn't take too long. Run the startapp command and it will create the base directory and files.
./manage.py startapp <appname>
All you then need to do is add the new app to INSTALLED_APPS, and create your admin.py file.
As your project gets bigger, keeping models in apps will keep it more organized. Many Django users create an app named utils (or similar) for the odd model.

Mixin Field into Existing and uneditable django model

I would like to mix a field into an existing model which I would rather not edit (it comes from a third party project and I would rather leave the project untouched). I have created a simple example which illustrates what I am trying but unable to do:
In an empty Django project I have created apps app1 and app2 (they are in that order in settings). They look like the following:
app1.models.py:
from django.db import models
from app2.models import BlogPost
class BlogPostExtend(models.Model):
custom_field_name = models.CharField(max_length=200)
class Meta:
abstract = True
BlogPost.__bases__ = (BlogPostExtend,)+BlogPost.__bases__ # this prevents MRO error
app2.models.py:
from django.db import models
class BlogPost(models.Model):
field_name = models.CharField(max_length=100)
Unfortunately this does not result in custom_field_name being created in the database when I syncdb, although at the command line if I type BlogPost.custom_field_name it does recognize it as a CharField. I know that in this simple case I could have BlogPost inherit from BlogPostExtend, but in the real use case I cannot edit BlogPost.
This is a very simplified example but it illustrates what I am trying to do.
Thanks!
Mixins work great with adding attributes and methods, but not fields.
In app1.models.py, do this instead:
from django.db import models
from app2.models import BlogPost
custom_field_name = models.CharField(max_length=200)
custom_field_name.contribute_to_class(BlogPost, "custom_field_name")
I think also the app1 app should come after app2 in INSTALLED_APPS for this to work.
Here is an explanation on contribute_to_class

Categories