OneToOneField(user) imply recreating all account? - python

I extended user class with a new class "Profile" using OneToOneField. It worked but now I can't reuse old account. (So user,superuser and admin). I get a "RelatedObjectDoesNotExist" Error since my old account do not have any "Profile". I suppose their is an other way than recreating accounts (Because I can't imagine it in production every new version) but I can't figure out how to update every old account. Does someone has any clue?

In some case, when you update your model(s), you have to write data migrations in addition to the schema migrations - see https://docs.djangoproject.com/en/1.10/topics/migrations/#data-migrations for additional information
In your case, you should create a data migration to create Profile object for every existing user. Follow the example in the documentation - it is pretty good.
One important note - you CAN'T just import your Profile model in the migration. You must do it like that:
Profile = apps.get_model("yourappname", "Profile")

Related

How to use the data about objects modifications in Django?

Django stores a history of the modification for every object, it is something we can access to through the Django admin:
It contains data about when the object was created/modified, the user who performed the action and the timestamp of the action:
By giving a look at the database, I can guess this data is stored in a default table called django_admin_log:
I am wondering if we can make use of this data in any way through the instance of a model ? I got used to adding manually my timestamps on every models through an Abstract Base Class, but I am wondering if it is useful in any way ?
Or this table records only the modification taking place in the Django admin panel, which would makes the custom timestamp still needed for when the models instance were to be updated outside it.
The history is only related to actions done in the admin view. To add metadata you can also use model_utils, which also offers some other handy functionalities: https://django-model-utils.readthedocs.io/en/latest/
Let us assume every action would be stored in a history table. This would indicate that you always have make a join in the db to get a view where each row also has created and updated information. This is quite some overhead. Therefore, keep it simple and add the timestamp to each model :)

How can I write my own permissions in django

I want to write my own permissions in Django, I mean I want to define exactly what a user can or cannot do, I have read this enter link description here
but it seems change_task_status is sth predefined in Django. for example, I want to define exactly users can have access to just get method of a view and just from row 1 to 8 of the database table, and sth like this. How can I do this?
Edit:
First of all, I did this with default permissions that are in auth_permission table in Django, for each model it creates permissions of add/view/change/delete in this table and I know that I can use it for my purpose. but I have two problems, first I don't want to use the default permission class od Django.contrib,auth model thus I want to create my own permission table (instead of auth_permissions I have mapp_permissions) it makes a problem for me now this new table is not filled with default permissions so I need to define permissions myself I mean I have to say what add_modelname means and also after I do this I need to define some new permissions that say for example for one model:user_x have permission view_modelname, users also have this permission but from data of this model which stored in database user_y just can see records of 1 to 8 of db table not all
Edit 2:
as you can see in permissions class comment it says:"it's
not currently possible to say "Mary may only change news stories that have a
certain status or publication date.""
how can I make it possible?
also, there should be a code inside Django files that define for the machine for example add_user which is in the table means what
According to Edit 2 , I see that you have some business logic related to permissions check , have a look at django-rules , I think it's what you're looking for.

Django-registration combine databases

I've installed the django-registration app succesfully and it works great.
But now I want that when people are logged in, they have to fill in more data about theirself.
Do I need to create an new django-app, so with a new database, or is it possible to save the data in the djano-registration app database (the database with username, password and e-mail)?
And how should I link these two databases, so everybody have his own, unique "index"-page with correct 'place'/link in/to the database?
Thanks a lot!
Look at the User-Profiles section of the auth application. It explains how to create a Profile object (basically a new table, not database), that is connected to the User object, and has whatever data you add to it. It can be retrieved with get_profile().
Just to highlight something in the docs - get_profile() does not automatically create a Profile for you, you need to manually create one each time a User is created. This Answer gives sample code for using Signals to create a profile - after a User is created, it sends a signal to any registered process. You would need to code, and register a profile-creation function with the signal.
The author of django-registration has also done a nice profile app. Wrapping around the User-Profiles.
Check it out at:
https://bitbucket.org/ubernostrum/django-profiles/

New field in Django model doesn't show up in admin interface or model forms

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?

In Django, how can you change the User class to work with a different db table?

We're running django alongside - and sharing a database with - an existing application. And we want to use an existing "user" table (not Django's own) to store user information.
It looks like it's possible to change the name of the table that Django uses, in the Meta class of the User definition.
But we'd prefer not to change the Django core itself.
So we were thinking that we could sub-class the core auth.User class like this :
class OurUser(User) :
objects = UserManager()
class Meta:
db_table = u'our_user_table'
Here, the aim is not to add any extra fields to the customized User class. But just to use the alternative table.
However, this fails (likely because the ORM is assuming that the our_user_table should have a foreign key referring back to the original User table, which it doesn't).
So, is this sensible way to do what we want to do? Have I missed out on some easier way to map classes onto tables? Or, if not, can this be made to work?
Update :
I think I might be able to make the change I want just by "monkey-patching" the _meta of User in a local_settings.py
User._meta.db_table = 'our_user_table'
Can anyone think of anything bad that could happen if I do this? (Particularly in the context of a fairly typical Django / Pinax application?)
You might find it useful to set up your old table as an alternative authentication source and sidestep all these issues.
Another option is to subclass the user and have the subclass point to your user-model. Override the save function to ensure that everything you need to do to preserve your old functionality is there.
I haven't done either of these myself but hopefully they are useful pointers.
Update
What I mean by alternative authentication in this case is a small python script that says "Yes, this is a valid username / password" - It then creates an instance of model in the standard Django table, copies fields across from the legacy table and returns the new user to the caller.
If you need to keep the two tables in sync, you could decide to have your alternative authentication never create a standard django user and just say "Yes, this is a valid password and username"

Categories