I have a Model of User. I want to assign new field 'role' to all of these users, Role connects User and his permissions.
Im trying to assign a default role that gives full acess to every existing and every new User, enabling admin to limit someones permissions by creating new Role.
I have looked for possible solutions on Stack Overflow: How do you specify a default for a Django ForeignKey Model or AdminModel field?
but they don't seem to work on Django 3.0.
def default_role():
all_user_permissions = CustomPermission.objects.all().filter(available_for_user=True)
return Role.objects.get_or_create(name=_("Unlimited"), permissions=all_user_permissions)[0]
class CustomUser(BaseUser):
...
role = models.ForeignKey('users.Role', verbose_name=_('role'), related_name='users', on_delete=models.CASCADE, default=default_role)
class Role(SafeDeleteTimeStampedModel):
permissions = models.ManyToManyField(CustomPermission, related_name='roles')
class CustomPermission(models.Model):
code = models.CharField(max_length=400, unique=True)
available_for_users = models.BooleanField(default=True)
When trying to makemigrations i get:
AttributeError: type object 'CustomUser' has no attribute 'default_role'
For me it would be better if the method returning default role was inside the class; but then i get the error: default_role() missing 1 required positional argument: 'self'
Related
I have a model named 'Clients' and another model named 'Information'.
class Information(models.Model):
client_name = models.ForeignKey(Clients, on_delete=models.SET(get_deleted_client_intance))
I want to set a custom text when a name is deleted from 'Clients' model.
The below function creates a new name 'deleted' as a new entry and is saved in 'Clients' model. I don't want that. I want if I delete a name it says 'deleted' or 'removed' on it's place.
def get_deleted_client_intance():
return Clients.objects.get_or_create(name='deleted')[0]
How can I do this?
I think you have a little misunderstanding about on_delete keyword argument. According to the docs:
When an object referenced by a ForeignKey is deleted, Django will emulate the behavior of the SQL constraint specified by the on_delete argument. For example, if you have a nullable ForeignKey and you want it to be set null when the referenced object is deleted:
user = models.ForeignKey(
User,
on_delete=models.SET_NULL,
blank=True,
null=True,
)
I.e. it handles some logic when a referenced object is deleted - sets the field as null (SET_NULL), restricts from removing if the referenced object has children (PROTECT), deletes the child objects as well (CASCADE), or sets your preferred value (SET), etc.
In your case, if you want to change the state of the Clients object you don't need to do it in the callable passed to models.SET, you'd better do it on the object level, e.g. override the delete method:
class Clients(models.Model):
...
def delete(self, using, *args, **kwargs):
self.name = 'deleted'
self.save(using=using)
I am building a simple class group app in which I am trying to add particular users from another model's ManyToFieldField to a new model's ManyToFieldField.
class ClassGroup(models.Model):
admins = models.ManyToManyField(settings.AUTH_USER_MODEL, related_name='admins')
members = models.ManyToManyField(settings.AITH_USER_MODEL)
title = models.CharField(max_length=9999, default='')
class ClassGroupInvite(models.Model):
class_group = models.ForeignKey(ClassGroup, on_delete=models.CASCADE)
invite_receiver = models.ManyToManyField(class_group.admins.all())
invite_sender = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
As you can see that I am filtering (send request only to class group admins) in ClassGroupInvite with setting ManyToManyField with ClassGroup.admins
But when I try this then it is showing
ManyToManyField(<django.db.models.fields.related_descriptors.ManyToManyDescriptor object at 0x000001CE78793280>) is invalid. First parameter to ManyToManyField must be either a model, a model name, or the string 'self'
I also read the documentation about it, But I didn't find anything about defining it.
then I tried using ClassGroup.admins.all then it showed
AttributeError: 'ManyToManyDescriptor' object has no attribute 'all'
I have tried many times but it is still not working, Any help would be much Appreciated. Thank You in Advance.
I'm getting this error:
user = models.OneToOneField(User)
TypeError: init() missing 1 required positional argument: 'on_delete'
from django.db import models
from django.contrib.auth.models import User
# Create your models here.
class UserProfileInfo(models.Model):
# creating relationship
user = models.OneToOneField(User)
# additional attributes
portfolio = models.URLField(blank=True)
picture = models.ImageField(upload_to='profile_pics', blank=True)
def __str__(self):
return self.user.username
As the error indicates, you need to specify what should happen, given the object to which you refer is removed, by the on_delete= parameter [Django-doc]. For example:
class UserProfileInfo(models.Model):
# creating relationship
user = models.OneToOneField(User, on_delete=models.CASCADE)
# additional attributes
portfolio = models.URLField(blank=True)
picture = models.ImageField(upload_to='profile_pics', blank=True)
def __str__(self):
return self.user.username
The options here are:
CASCADE
Cascade deletes. Django emulates the behavior of the SQL constraint
ON DELETE CASCADE and also deletes the object containing the
ForeignKey.
Model.delete() isn't called on related models, but the pre_delete
and post_delete signals are sent for all deleted objects.
PROTECT
Prevent deletion of the referenced object by raising ProtectedError,
a subclass of django.db.IntegrityError.
SET_NULL
Set the ForeignKey null; this is only possible if null is True.
SET_DEFAULT
Set the ForeignKey to its default value; a default for the
ForeignKey must be set.
SET()
Set the ForeignKey to the value passed to SET(), or if a callable
is passed in, the result of calling it. In most cases, passing a
callable will be necessary to avoid executing queries at the time your
models.py is imported (...)
DO_NOTHING
Take no action. If your database backend enforces referential
integrity, this will cause an IntegrityError unless you manually add
an SQL ON DELETE constraint to the database field.
A similar question is answered here Getting TypeError: __init__() missing 1 required positional argument: 'on_delete' when trying to add parent table after child table with entries
Basically following should fix url problem
From Django 2.0 on_delete is required:
user = models.OneToOneField(User, on_delete=models.CASCADE)
put 'on_delete = models.CASCADE' in the constructor
what it does: when you will delete the user object as you have referenced it in the user field of your model. it will also delete the model object of UserProfileInfo for taht particular user.
Question / Problem:
I am building a Django app, with 2 models: User and Secret. Secrets can be made by Users, and other Users can "like" them. I've setup my likes field as a ManyToManyField, so that Users whom like a Secret can be stored there and later retrieved, etc. However, when I try to query for a User and a Secret and use my_secret.likes.add(my_User) nothing happens. I don't receive an error and when I print my Secret's many-to-many likes field, after the add, I see: secrets.User.None.
Why is my add() method running but I am not receiving any errors, and why is my User not properly being added to my Secret's likes?
Note: I've saved both the User and Secret objects upon initial creation. Outside this application I've been able to use the add() method just fine, but in those scenarios I was creating objects in the moment, and not retreiving already existing objects.
Is there a different way to handle add() when using data retreived from a Query? That's my only other line of reasoning right now, and I've followed the documentation here exactly: Django Many-to-Many Docs
I also apologize if this was answered elsewhere on the site. I did find one other post here, but there was no solution provided, granted they were experiencing the exact same issue.
My Models:
class User(models.Model):
"""
Creates instances of a `User`.
Parameters:
-`models.Model` - Django's `models.Model` method allows us to create new models.
"""
first_name = models.CharField(max_length=50) # CharField is field type for characters
last_name = models.CharField(max_length=50)
email = models.CharField(max_length=50)
password = models.CharField(max_length=22)
created_at = models.DateTimeField(auto_now_add=True) # DateTimeField is field type for date and time
updated_at = models.DateTimeField(auto_now=True) # note the `auto_now=True` parameter
objects = UserManager() # Attaches `UserManager` methods to our `User.objects` object.
class Secret(models.Model):
"""
Creates instances of a `Secret`.
Parameters:
-`models.Model` - Django's `models.Model` method allows us to create new models.
"""
description = models.CharField(max_length=100) # CharField is field type for characters
user = models.ForeignKey(User, related_name="secrets") # One-to-Many Relationship
likes = models.ManyToManyField(User) # Many to Many Relationship
created_at = models.DateTimeField(auto_now_add=True) # DateTimeField is field type for date and time
updated_at = models.DateTimeField(auto_now=True) # note the `auto_now=True` parameter
objects = SecretManager() # Attaches `SecretManager` methods to our `Secret.objects` object.
Problem Example:
The model migrates fine, everything seems to be in proper syntax. However, when I try and retrieve a User and a Secret, and add the User to the Secret.likes, the add() method gives no errors, runs, but no objects are saved.
Here's an example:
tim = User.objects.get(email="tim#tim.com") # Gets a user object
my_secret = Secret.objects.get(id=2) # Gets a secret object
# This is where nothing seems to happen / take:
my_secret.likes.add(tim) # add() method per Django many-to-many docs
print my_secret.likes # returns: `secrets.User.None` -- why?
Why when printing my_secret.likes above, is nothing printed?
Especially when:
tim.secret_set.all() shows the secret containing an id=2 as in the above example....so the User is recording the relationship with the Secret, but the Secret is not recording any relationship with the User. What am I doing wrong?
You need to call the all method of the many-to-many field to view all related objects:
print my_secret.likes.all()
# ^^^^^
I have a model which is an extension of a User model in Django 1.8. I am also connecting to a MySQL database for this.
class LibraryUser(models.Model):
user_id = models.OneToOneField(User)
is_catalogue_subscriber = models.BooleanField(default=True)
is_research_subscriber = models.BooleanField(default=True)
library_membership_number = models.CharField(max_length=64)
The reason why I extended the User model, of course is to use the authentication framework.
So now, I want to create a new LibraryUser using the library_membership_number as the login username. How should I do so? Do I create the User first then reference the LibraryUser?
ie given some_ variables either received by a POST or by migration of users to the new table
u = User.objects.create_user(email=some_email, password=some_password)
lu = LibraryUser(library_membership_number, user_id = u.id)
lu.save()
Or is there a correct way to do this? Tried finding online but can't find something to particularly address this problem.
You should assign value to the specify fields as the following:
lu = LibraryUser(library_membership_number= '...', user_id = user)
lu.save()
library_membership_number
You can't just assign a variable to library_membership_number. model is a object containing the fields. You should appoint the field and assign it: library_membership_number= '...', or model can't parse which field you will store.
user_id
It has defined foreignkey in advance. It can accept another model object to store: user_id = user. Don't call attribute of the user to store in LibraryUser.