Migrate model while adding user foreign key - django

So i have this model where I added user field as foreign key to User model
from django.db import models
from django.contrib.auth.models import User
from django.conf import settings
class Post(models.Model):
url = models.URLField()
title = models.CharField(max_length=140)
user = models.ForeignKey(settings.AUTH_USER_MODEL)
Than I run
python3 manage.py makemigrations
And get:
You are trying to add a non-nullable field 'user' to comment 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)
2) Quit, and let me add a default in models.py
I understand that I need to give it default user but I don't get how to do that.
P.S. Django version - 1.8.3

Ok, so it happens migration utility's question hadn't appeared intuitive enough for me. What migration utility was really asking were required fields of User model. So basically you need to type in some data 3 times (for username, password and email). The problem is utility isn't really saying what field is it expecting.

Related

How to login to Django Admin panel with user I created in this panel? User model was extended

The model itself:
from django.db import models
from django.contrib.auth.models import AbstractUser
class UserModel(AbstractUser):
class UserType(models.TextChoices):
MANAGER = 'm', 'Manager'
CUSTOMER = 'c', 'Customer'
first_name = models.CharField(max_length=120)
last_name = models.CharField(max_length=120)
type = models.CharField(choices=UserType.choices, max_length=1)
USER_MODEL is registered in settings.py.
in admin.py it's registered as:
from django.contrib import admin
from .models import UserModel
admin.site.register(UserModel)
I can create new model in the panel with existing superuser I have. i.e. - it works.
I can add new super users with manage.py and they appear in the same place in the panel.
But later on I can't login with users I created in that panel.
saff status - checked.
The problem might be with passwords, because those created with createsuperuser shown hashed in the panel or I don't know even.
If I did smth completely wrong - let me know, I only need to extend users to have a couple of additional fields.
Django version 3.2
No worries django doesn't store raw passwords it always hash the password for security reasons, imagine someone hacked into your database people usually use the same password for all websites, not nice huh?!
so try python manage.py changepassword <user_name> and write your new password
and access the shell to check is_staff attr

How do I set a default user for blog posts in Django?

My Blog model has a User field like following:
from django.contrib.auth.models import User
class Blog:
author = models.ForeignKey(User, on_delete = models.CASCADE, related_name='blog', default=User('monty'))
This works as in I can see 'monty' set as a default user in the admin interface when I create a blog post. However, when I make migrations, I get the following error:
ValueError: Cannot serialize: <User: >
There are some values Django cannot serialize into migration files.
I also tried this:
default=User.objects.filter(username='monty'))
and that returns a slightly different error when I make migrations:
ValueError: Cannot serialize: <User: monty>
There are some values Django cannot serialize into migration files.
Does anyone know how to get past this error?
You can make a callable that determines the User object, so:
from django.conf import settings
from django.contrib.auth import get_user_model
def get_monty():
if get_monty.user:
return user
user, __ = get_user_model().get_or_create(username='monty')
get_monty.user = user
return user
get_monty.user = None
class Blog(models.Model):
author = models.ForeignKey(
settings.AUTH_USER_MODEL,
on_delete=models.CASCADE,
related_name='blog',
default=get_monty
)
That being said, I think it makes no sense to specify a default here. Your views can determine the logged in user and set that as the author. By using a default you likely will eventually end up with some Posts for which the view did not implement the logic, and are thus all assigned to monty, it
thus will silence an error that probably should not be silenced.
Note: It is normally better to make use of the settings.AUTH_USER_MODEL [Django-doc] to refer to the user model, than to use the User model [Django-doc] directly. For more information you can see the referencing the User model section of the documentation.

How to design the user table in database?

I want to develop a server side of an app that holds users.
Of course I need a table in database holding the user information.
At first I may write
class User(models.Model): # using django models
userid = ...
password = ...
which gives me a database table containing userid and password.
However, I might want to add some attributes (maybe Credit, Birthday...so on) to each user in the future. I just can't think up all of them right now. And I can't know what attributes I would really need in the future.
How can I deal with it?
There's already a user table in Django. This table is automatically create when you first apply the migration with 'manage.py migrate' command.
In database schema, this table is listed as auth_user and you can import it into Django with the following command
from django.contrib.auth.models import User
Django provides a default model for User. you can use it like this.
from django.contrib.auth.models import User
and as per your second query. you can do so by creating another model and adding a ForeignKey or OneToOneField of User model to link it with each user.
class Customuserprofile(models.Model):
user=models.OneToOneField(settings.AUTH_USER_MODEL)
credit=models.CharField()
birthday=models.DateTimeField()
well, if you want to add some field to the User you can use AbstractUser or AbstractBaseUser model read this that explain the differences and give a example https://simpleisbetterthancomplex.com/tutorial/2016/07/22/how-to-extend-django-user-model.html#abstractbaseuser

Django: 'no such table' after extending the User model using OneToOneField

(Django 1.10.) I'm trying to follow this advice on extending the user model using OneToOneField. In my app 'polls' (yes, I'm extending the app made in the 'official' tutorial) I want to store two additional pieces of information about each user, namely, a string of characters and a number.
In my models.py I now have the following:
from django.contrib.auth.models import User
class Employee(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
stopien = models.CharField(max_length=100)
pensum = models.IntegerField()
and in admin.py the following:
from django.contrib.auth.admin import UserAdmin as BaseUserAdmin
from django.contrib.auth.models import User
from polls.models import Employee
class EmployeeInline(admin.StackedInline):
model = Employee
can_delete = False
verbose_name_plural = 'employee'
class UserAdmin(BaseUserAdmin):
inlines = (EmployeeInline, )
admin.site.unregister(User)
admin.site.register(User, UserAdmin)
When adding a user using the admin panel my two new fields display correctly. However, when I click 'save', or if I don't add any user and just click on the name of my sole admin user in the admin panel, I get the following error:
OperationalError at /admin/auth/user/1/change/
no such table: polls_employee
I see some questions and answers related to similar problems, but they seem to be relevant for older version of Django. Could anyone give me a tip as to what I should do? Ideally I'd want my two additional fields display in the admin panel, though I suspect this might be a task for the future.
I have to confess I do not understand this paragraph from the documentation just following the advice I'm using:
These profile models are not special in any way - they are just Django models that happen to have a one-to-one link with a User model. As such, they do not get auto created when a user is created, but a django.db.models.signals.post_save could be used to create or update related models as appropriate.
Do I need to tie this 'post-save' to some element of the admin panel?
I'd be very greatful for any help!
You need run makemigrations to create a migration for your new model, and then migrate to run the migration and create the database table.
./manage.py makemigrations
./manage.py migrate

IntegrityError after customizing user model

After customizing my user model in Django Oscar, I received the following error message:
IntegrityError at /
insert or update on table "basket_basket" violates foreign key constraint "basket_basket_owner_id_74ddb970811da304_fk_auth_user_id"
DETAIL: Key (owner_id)=(5) is not present in table "auth_user".
To customize my user model, I followed the instructions here.
First, I wrote the following models.py file, located within my project directory at apps/user/models.py.
from django.db import models
from oscar.apps.customer.abstract_models import AbstractUser
from django.contrib.postgres.fields import ArrayField
class User(AbstractUser):
acct_bal = models.DecimalField(max_digits=10, decimal_places=2, default=0.00)
purchased_items = ArrayField(models.IntegerField(), default=list)
The idea is that I want the user to have an account balance (which I will use for payment later) as well as a list of product numbers representing items that have already been purchased.
After making models.py, I edited the installed apps as follows:
INSTALLED_APPS = [...
'shopworld.apps.user',
] + get_core_apps()
And then put this at the bottom of my settings.py:
AUTH_USER_MODEL = 'user.User'
I then did ./manage.py migrate, but for some reason I am getting this error message. I also tried dropping the django_admin_log table as suggested here, but it did not work. Any help would be greatly appreciated.
I fixed this - the issue was that I was trying to migrate to a custom user model after already having done migrations with auth_user. This meant that auth_user didn't update correctly. I had to flush and re-sync the database, so that the initial migration captured the custom user model.