Django: ImageField sets wrong url - django

I am new to django and set up my first project with one app in the beginning. Some time later I figured out that I need a custom user model so I've created a second app with the custom user model as I've read somewhere that you need the user model as first migration (I'm telling this, because I believe my project structure is causing my problem).
Right now I am working on an avatar upload for the user model.
I am able to upload an image via DRF and then open the image in my browser, but not with the saved url in my database.
Django saves the image like this in the database: http://localhost:8000/api/users/<user_id>/media/avatars/image.jpg.
But the correct url would be: http://localhost:8000/media/avatars/image.jpg
How do I make django save the correct url?
I've set MEDIA_ROOT and MEDIA_URL like this:
MEDIA_ROOT = BASE_DIR + 'media'
MEDIA_URL = 'media/'
My project structure:
my project
- backend (first app)
- - manage.py
- - settings.py
- users (second app)
- - models.py # here is my custom user model
The custom user model:
class User(AbstractBaseUser, PermissionsMixin):
username_validator = UnicodeUsernameValidator()
username = models.CharField(
_('username'),
max_length=150,
unique=True,
help_text=_('Required. 150 characters or fewer. Letters, digits and #/./+/-/_ only.'),
validators=[username_validator],
error_messages={
'unique': _("A user with that username already exists."),
},
)
email = models.EmailField(_('email address'), unique=True)
is_staff = models.BooleanField(
_('staff status'),
default=False,
help_text=_('Designates whether the user can log into this admin site.'),
)
date_joined = models.DateTimeField(_('date joined'), auto_now_add=True)
is_active = models.BooleanField(
_('active'),
default=True,
help_text=_(
'Designates whether this user should be treated as active. '
'Unselect this instead of deleting accounts.'
),
)
avatar = models.ImageField(
upload_to='avatars/',
null=True,
blank=True
)
objects = UserManager()
EMAIL_FIELD = 'email'
USERNAME_FIELD = 'username'
REQUIRED_FIELDS = ['email']
class Meta:
db_table = 'auth_user'
verbose_name = _('user')
verbose_name_plural = _('users')
def email_user(self, subject, message, from_email=None, **kwargs):
"""Send an email to this user."""
send_mail(subject, message, from_email, [self.email], **kwargs)
Any help is appreciated

Try change your settings.py to absolute paths:
MEDIA_ROOT = '/var/www/your_project_path/media/'
MEDIA_URL = '/media/'
Remember about slashes / /

Related

inactive page after signin to social media on django allauth

Iam trying to develope a website that use socail media for authentication based on google and facebook.
I used django-allauth library for it.
but I have problem with this when user create account or signin via google. after successfully signin return inactive page. I want to redirect to my home page
there is my custom model
there is my custome models
class Account(AbstractBaseUser):
USERNAME_FIELD = "email"
first_name = models.CharField(max_length=100)
last_name = models.CharField(max_length=100)
email = models.EmailField(max_length=100, unique=True)
username = models.CharField(max_length=100, unique=True)
profile_pic = models.ImageField(
null=True, upload_to=image_path_generator, blank=True
)
total_storage = models.FloatField(
default=20, validators=[MinValueValidator(0.0), MaxValueValidator(20.0)]
)
used_storage = models.FloatField(
default=0, validators=[MinValueValidator(0.0), MaxValueValidator(20.0)]
)
phone_no = models.IntegerField(default=0)
user_key = models.CharField(max_length=100, blank=True, null=True)
joined_date = models.DateTimeField(default=timezone.now)
two_auth = models.CharField(
choices=twoAuth_choices, max_length=20, default=twoAuth_choices[1][1]
)
files = models.ManyToManyField(
"fileuploads.NewFile",
related_name="file_owner",
)
folders = models.ManyToManyField(
"folders.Folder",
related_name="folder_owner",
)
# required
date_joined = models.DateTimeField(auto_now_add=True)
last_login = models.DateTimeField(auto_now_add=True)
is_admin = models.BooleanField(default=False)
is_staff = models.BooleanField(default=False)
is_active = models.BooleanField(default=False)
is_superadmin = models.BooleanField(default=False)
REQUIRED_FIELDS = ["username", "first_name", "last_name"]
objects = AccountManager()
i have also setup my settings.py to like this
# SOCIAL CONNECTION
SITE_ID = 1
SOCIALACCOUNT_LOGIN_ON_GET = True
ACCOUNT_AUTHENTICATION_METHOD = "email"
ACCOUNT_EMAIL_REQUIRED = True
ACCOUNT_USERNAME_REQUIRED = False
ACCOUNT_EMAIL_VERIFICATION = "none"
LOGIN_REDIRECT_URL = "/"
LOGOUT_REDIRECT_URL = logout_url
could you please help me with this?
I think you have to wrap each view with the #login_required decorator and set the login_url argument equal to the home. Something like this:
#login_required(login_url='/example url you want redirect/')
There is another SO thread for this here: How to specify the login_required redirect url in django?

how to use custom user model for django-graphql-auth

I am using graphql in my project and want to generate token while registration. Even though django-graphql-auth has all the written mutation, it uses a different user model. But I want to use my custom user model. What should I do?
This is my user model
class CustomUser(AbstractUser):
"""
Customized User Model
"""
email = models.EmailField(blank=True, null=True,
max_length=256, unique=True)
mobile_no = models.CharField(
max_length=20, blank=True, null=True, unique=True)
verification_code = models.CharField(max_length=6)
code_valid_till = models.DateTimeField(blank=True, null=True)
timezone = models.CharField(max_length=40, blank=True, null=True)
country = models.CharField(max_length=20, default='BD', choices=COUNTRIES)
pin_verified = models.BooleanField(default=False)
email_verified = models.BooleanField(default=False)
modified_on = models.DateTimeField('date modified', auto_now=True)
created_on = models.DateTimeField(auto_now_add=True)
# For password reset
reset_verification_code = models.CharField(
max_length=6, blank=True, null=True)
reset_code_valid_till = models.DateTimeField(blank=True, null=True)
reset_request = models.BooleanField(default=False)
reset_valid_till = models.DateTimeField(blank=True, null=True)
class Meta:
verbose_name_plural = "User"
def __str__(self):
if not self.is_anonymous:
return "{} - {}".format(self.mobile_no, self.email)
else:
return "Anon"
#property
def get_full_name(self):
return super().get_full_name()
def get_all_permissions(self, obj=None):
return super().get_all_permissions(obj=obj)
def send_email(self, subject, message, to_email: list, from_email=None, **kwargs):
send_mail_to_user(subject, message, from_email, to_email, **kwargs)
I'm the author of the package. Now the documentation site has a custom user model in the quickstart, you can see it here. Currently, it's not documented how to use it with a custom user model, but it is already an open issue, you can see it here. I will paste the same answer that is on the Github.
From Django docs:
Changing to a custom user model mid-project
Changing AUTH_USER_MODEL after you’ve created database tables is
significantly more difficult since it affects foreign keys and
many-to-many relationships, for example.
So, make sure to create the custom user model when you start your project.
Add the following to your custom user model
Following the Django custom user model.
from django.contrib.auth.models import AbstractUser
class CustomUser(AbstractUser):
# ...
USERNAME_FIELD = "<username_filed_name>" # e.g: "username", "email"
EMAIL_FIELD = "<email_field_name>" # e.g: "email", "primary_email"
Add your custom user model in the settings
See here for more info.
# settings.py
AUTH_USER_MODEL = 'myapp.CustomUser'
Please let me know if you have further questions :)
Edit: Add the mobile_no in the registration
Use the REGISTER_MUTATION_FIELDS or REGISTER_MUTATION_FIELDS_OPTIONAL.
# settings.py
GRAPHQL_AUTH = {
# ...
REGISTER_MUTATION_FIELDS = [
# ...
'mobile_no'
]
# or
REGISTER_MUTATION_FIELDS_OPTIONAL = ['mobile_no']
# You can set the graphene base scalars:
REGISTER_MUTATION_FIELDS = {
"email": "String",
"username": "String",
"mobile_no": "String",
}
}

Store checkbox value in db's new column - react/django

I've been trying to store value of one checkbox, promo_consent, sent from a form into a new column that I've just created in the DB.
Whatever I do it stores always TRUE no matter wheter the checkboxed was checked or not, or stores always FALSE no matter wheter the checkboxes was checked or not.
I have this model:
class User(AbstractBaseUser, PermissionsMixin, PagePermissionMixin):
"""User model for both staff and clients.
It consists of base AbstractBaseUser class and has 2 permissions mixins.
One of them is for standard django permissions and the second is
for Page object permissions.
Note:
This model is used for OAuth2 and Django authentication.
"""
first_name = models.CharField(_('first name'), max_length=30, blank=True)
last_name = models.CharField(_('last name'), max_length=30, blank=True)
email = models.EmailField(_('email address'), unique=True, blank=True)
new_email = models.EmailField(_('new email'), blank=True)
is_staff = models.BooleanField(
_('staff status'),
default=False,
help_text=_('Designates whether the user can log into this admin '
'site.'))
is_active = models.BooleanField(
_('active'),
default=True,
help_text=_('Designates whether this user should be treated as '
'active. Unselect this instead of deleting accounts.'))
date_joined = models.DateTimeField(
_('date joined'),
default=timezone.now)
promo_consent = models.BooleanField(
_('Promo consent'),
default=False,
help_text=_('Shows whether user has agreed to be notified about '
'news and promo sales'))
....
....
....
and this serializer:
class RegistrationSerializer(SerializerSchemaMixin, serializers.Serializer,
SerializerValidateMixin,
EmailUniquenessValidationMixin,
PasswordValidationMixin):
"""Registration serializer."""
first_name = serializers.CharField(max_length=30, default='')
last_name = serializers.CharField(max_length=30, default='')
email = serializers.EmailField(required=True)
password = serializers.CharField(max_length=100, required=True)
password2 = serializers.CharField(max_length=100, required=True)
rules = serializers.BooleanField(required=True)
promo_consent = serializers.BooleanField(required=False)
def validate_rules(self, value):
"""Checks if 'rules' is True."""
if not value:
raise serializers.ValidationError(_('Rules has to be checked'))
else:
return value
def promo_consent(self, value):
return true
def validate(self, data):
"""Override serializer.validate()."""
self.validate_passwords_uniformity(data)
return data
def save(self, **kwargs):
"""Register new user and send confirmation email."""
language = kwargs['language']
email = self.validated_data['email']
promo_consent = self.promo_consent
self.instance = User(first_name=self.validated_data['first_name'],
last_name=self.validated_data['last_name'],
email=email,
is_active=False,
email_confirmation=uuid.uuid4().hex)
self.instance.set_password(self.validated_data['password'])
self.instance.save()
self.instance.send_email_confirmation(language, email)
return self.instance
I've been working this the second day. What am I missing here?

How to properly extend Django user?

I want to extend the Django user class in Django 1.7.1 to drop the first name and last name and to put a unique constraint on the e-mail address. So far I have this custom model to change the constraints/fields:
class ExtUser(AbstractBaseUser, PermissionsMixin):
class Meta:
# Django 1.7.2?
#default_related_name = 'user'
db_table = 'auth_user'
verbose_name = _('user')
verbose_name_plural = _('users')
abstract = False
username = models.CharField(_('username'), max_length=30, unique=True,
help_text=_('Required. 30 characters or fewer. Letters, digits and '
'#/./+/-/_ only.'),
validators=[
validators.RegexValidator(r'^[\w.#+-]+$', _('Enter a valid username.'), 'invalid')
])
email = models.EmailField(_('email address'), max_length=75, blank=False, null=False, unique=True)
is_staff = models.BooleanField(_('staff status'), default=False,
help_text=_('Designates whether the user can log into this admin '
'site.'))
is_active = models.BooleanField(_('active'), default=True,
help_text=_('Designates whether this user should be treated as '
'active. Unselect this instead of deleting accounts.'))
date_joined = models.DateTimeField(_('date joined'), default=timezone.now)
objects = UserManager()
USERNAME_FIELD = 'username'
REQUIRED_FIELDS = ['email']
def get_short_name(self):
return self.username
def email_user(self, subject, message, from_email=None, **kwargs):
send_mail(subject, message, from_email, [self.email], **kwargs)
And I modified the settings file:
AUTH_USER_MODEL = 'ext.ExtUser'
I can login to the Django admin, but when I try to edit a user, I get the following exception:
ProgrammingError at /api/extuser/1/
column auth_user_groups.extuser_id does not exist
LINE 1: ...oup"."id" = "auth_user_groups"."group_id" ) WHERE "auth_user...
I guess the user foreign key in other tables is formed based upon the class name... How do I fix this? I tried using the default_related_name field in the model meta class, but that had no positive effect.
Thanks in advance for any help!
Kind regards,
K.
OK, so I found a solution for my problem: make sure that the custom user model class is named "User" instead of "ExtUser" and everything will keep on working.
Easy! :-)

Django 1.5: Understanding of AbstractBaseUser and permissions

I created an user app MyUser which is an extension of AbstractBaseUser. I was under the impression that the model MyUser will replace the standard Auth.User, as long as it is mentioned in settings.py
AUTH_PROFILE_MODULE = 'profile.MyUser'
My trouble is now that I can't set the permissions for users registered in the MyUser model. When I try to set the group memberships and permissions, I get the error User' instance expected, got <MyUser: username>.
How can I add users of my user model to the permissions and correct groups?
class MyUserManager(BaseUserManager):
def create_user(self, username, email, phone, password=None, company=False):
if not email:
raise ValueError('Users must have an email address')
if not username: username = email.split('#')[0]
user = self.model(
email=MyUserManager.normalize_email(email),
username=username,phone=phone,)
user.set_password(password)
user.save(using=self._db)
# add to user group and set permissions
if company:
g = Group.objects.get(name='company')
p = Permission.objects.get(codename='add_company')
else:
g = Group.objects.get(name='user')
p = Permission.objects.get(codename='add_user')
g.user_set.add(user)
user.user_permissions.add(p)
return user
class MyUser(AbstractBaseUser):
username = models.CharField(max_length=254, unique=True, blank=True, null=True)
email = models.EmailField(max_length=254, unique=True, db_index=True)
phone = models.CharField(_('Phone Number'), max_length=25, blank=True, null=True,)
is_active = models.BooleanField(default=True)
is_admin = models.BooleanField(default=False)
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = ['phone']
objects = MyUserManager()
def get_full_name(self):
return self.email
...
Just add PermissionsMixin to your model declaration! :)
class MyUser(AbstractBaseUser, PermissionsMixin):
...
Here is the relevant part of Django docs.
You've probably resolved your issue but for completeness did you mean to refer to setting AUTH_USER_MODEL vs AUTH_PROFILE_MODULE when creating a custom user model in Django 1.5.
ref: https://docs.djangoproject.com/en/1.5/topics/auth/customizing/#substituting-a-custom-user-model