i'm happy with django built in user/auth , i just want to add some fields to it and change table name (mostly the last one , i can use another table for custom fields )
so i searched around and apparently we can use subclass as suggested on Rename Django's auth_user table?
So i have to start a new app and use it's model to as a subclass for AbstractUser or there is another way? (After all i just want to use it's model and other parts of app are useless )
anyway i created a new project / started app called customuser and in its model i have this code
customuser/models.py
from django.db import models
from django.contrib.auth.models import AbstractUser
class customuser(AbstractUser):
class Meta:
swappable = 'AUTH_USER_MODEL'
db_table = 'customuser'
i ran makemigrations AND migrate ... it's done successfully
but atill the tables with default name was created in database as you can see below ... am i missing something ?
To use a custom user model, you need to set the AUTH_USER_MODEL setting in your settings module.
Note that you don't need to set swappable = 'AUTH_USER_MODEL'. This is an undocumented and private attribute, and is probably better left untouched.
Quite frankly if you're still in the position to do it, i'd just start a new app. It says in the docs that this decision is best made before starting your project because its a pain in the ... its hard.
If you intend to set AUTH_USER_MODEL, you should set it before creating any migrations or running manage.py migrate for the first time.
The solution otherwise is to dumpdata from the database, and manually tweak it so any reference to the user class in your dump file is replaced with your new user class. then you need to create some migrations to change the schema.
So it is doable. its just much simpler to start from a fresh project.
Django allows you to override the default User model by providing a value for the AUTH_USER_MODEL setting that references a custom model
AUTH_USER_MODEL = 'myapp.MyUser'
This dotted pair describes the name of the Django app (which must be in your INSTALLED_APPS), and the name of the Django model that you wish to use as your user model.
A full example of an admin-compliant custom user app can be found on the Django Project website.
Related
I am new to django, so please excuse if I am totally wrong.
I have a django installation in which some tables are manually imported from outside source. There is one table with large number of fields. In my current django I need to interact with only few of its fields.
Can I create a django model for that table with just the fields I need and will it work? Will it mess up migrations completely? How is such a situation usually handled in django?
You can use meta option db-table and managed
class ModelWithFewFields(models.Model):
# Fields declare here
class Meta:
db_table = 'Real_DB_TABLE_NAME'
managed = False
I am developing a django application using Pinax Stripe(https://github.com/pinax/pinax-stripe). Pinax stripe is a bundled application which has a model called 'Plans'. Now in my application, I want to add some extra fields to the model 'Plans' in my application BUT without modifying the original pinax stripe application.
Something like this:
#models.py
from pinax-stripe.models import Plan
class UserProfile(models.Model):
#write the extra fields here
Is there any way I can do it and then register it with admin so i can add data to those fields in admin panel?
You can inherit the Plan models and add your own attributes:
from pinax-stripe.models import Plan
class MyPlan(Plan):
# add your attributes
pass
This works like normal inheritance in python, plus your custom attributes are migrated when you run a migration because the original pinax Plan is a subclass of models.Model.
However, be careful to not use attribute names that already exist in the pinax Plan model, since your new model will automatically take all the attibutes from Plan and Django cannot write migrations for duplicate fields.
You can simply subclass Plan and add whatever fields / methods you want:
from pinax-stripe.models import Plan
class UserProfile(Plan):
#write the extra fields here
I'd recommend you, use the OneToOne relationship like Django docs recommend to use in the User model
from pinax-stripe.models import Plan
class UserProfile(models.Model):
plan = models.OneToOneField(Plan , on_delete=models.CASCADE)
#write the extra fields here
You can download pinax folder from https://github.com/pinax/pinax-stripe into your app and edit models.py and admin.py files as per your requirement.
I am really stuck in my project right now. I am trying to implement Oauth2 for my app. I found out about django-oauth2-provider a lot and tried it. The only problem is, it uses the User model at django.contrib.auth. The main users of our site are saved in a custom model called User which does not inherit from or extend the model at django.contrib.auth.
Is there any way to use my custom User model for creating clients and token?
If django-oauth2-provider can't be used for this purpose, can anyone recommend me some oauth2 library with the option to implement oauth2 with my own model.
Sincerely,
Sushant Karki
As the previous answer suggested, you should extend AbstractUser from django.contrib.auth.models.
The problem with the access token that the OP referring to, occur when changing the setting AUTH_USER_MODEL AFTER django-oauth2-provider was migrated.
When django-oauth2-provider is migrated, it creates a key constrain between the User model and django-oauth2-provider.
The solution is very easy:
Create your new User model and change the AUTH_USER_MODEL setting.
Go to the django_migration table in your database.
Delete all rows of django-oauth2-provider.
run python manage.py makemigrations
run python manage.py migrate
Now, the django-oauth2-provider tables are connected to the RIGHT User model.
django-oauth2-provider fetches the user model using settings.AUTH_USER_MODEL, with a fallback to auth.User. If you extend AbstractUser your User model will include all the fields of auth.User plus any additional fields you specify.
from django.contrib.auth.models import AbstractUser
from django.db import models
class User(AbstractUser):
some_additional_field = models.BooleanField(default=False)
Specify the user model to be used like this in settings.py:
AUTH_USER_MODEL = 'user_api.User'
If you don't want to base your user on AbstractUser you'll also need to write your own user manager, e.g. by extending the BaseUserManager
You can read more about ways to customize django's user model here.
I've a table name UGC and would like to clear all the data inside that table. I don't want to reset the entire app which would delete all the data in all the other models as well. Is it possible to clear only one single model? I also have South configured with my app, if that would help.
You could use raw SQL :
cursor.execute(“DROP TABLE UGC”)
or you could just use the ORM directly inside a Django shell :
UGCModel.objects.all().delete()
That would erase the data (not the table, though), so you have to be careful :)
Another way (for completeness and to make use of South) would be to comment out the model in your models declaration, migrate and then put it back again (assuming there are no models with a reference to it.)
HTH
In the admin interface, you can go to the list page for that model, then you can select all models and use the Delete selected ... action at the top of the table.
Remember that, in whatever way you delete the data, foreign keys default to ON DELETE CASCADE, so any model with a foreign key to a model you want to delete will be deleted as well. The admin interface will give you a complete overview of models that will be deleted.
Faced such issues today with django 2.0.2 because i created my model with
class Front(models.Model):
pass
and migrated it but when i later updated the model, i couldn't run
python manage.py makemigrations because it was saying
You are trying to add a non-nullable field 'update' to front without a default; we can't do that (the database needs something to populate existing rows).
Please select a fix:
1) Provide a one-off default now (will be set on all existing rows
with a null value for this column)
2) Quit, and let me add a default in models.py
Select an option:
What was my solution?
I choose option 2 which is to quit
I commented out the troublesome model/table which is Front in my case
I ran python manage.py makemigrations which deleted the troublesome table/model
I uncommented my model and ran python manage.py makemigrations again which recreated the table/model and finally
I migrated my changes with python manage.py migrate and everyhing was resolved!
Note: Be careful with the above instruction cause it will delete all references/foreign keys to the table/model with on_delete=models.CASCADE which is the default!
Django 3.1.14
If you're interested in doing it on the command line, and you'll be doing this type of cleaning of your db frequently, I do this:
# project_name/app_name/management/commands/clear_test_models.py
from django.core.management.base import BaseCommand
from django.apps import apps
keep_models = ['KeepModel0', 'KeepModel1']
class Command(BaseCommand):
"""
clear all in app_name app except listed in keep_models list
"""
help = 'clear all models except those listed in keep_models list'
def handle(self, *args, **kwargs):
my_app = apps.get_app_config('app_name')
my_models = my_app.get_models()
for model in my_models:
if model.__name__ not in keep_models:
model.objects.all().delete()
To run on the command line:
DJANGO_SETTINGS_MODULE=app_name.settings.local python manage.py clear_test_models
I've created a model in one of my apps which works fine. However, I needed to add a new field. I did this, and used manage.py reset <appname> to drop the tables and add them again. This process went fine - the new field appears in the database. However, I can't get the field to show up in the admin interface, nor in the custom model form I've created. Because I haven't given it a default value (and don't want to, nor should I need to) I can't use either method to add a row into the database. Any ideas?
Model snippet:
use_balance = models.BooleanField()
Have you restarted your server?
By any chance, did you forget to update your ModelAdmin definitions?