I'm trying to extend the default form and remove the labels for Django-allauth signup form. Most labels are removed successfully, but I'm not able to remove the label for the email field.
forms.py
from django import forms
from .models import Profile
class SignupForm(forms.ModelForm):
gender = forms.CharField(max_length=1, label='Gender')
first_name = forms.CharField(max_length=50, label='First Name')
last_name = forms.CharField(max_length=50, label='Last Name')
birthday = forms.CharField(max_length=50, label='Birthday')
location = forms.CharField(max_length=50, label='Location')
def __init__(self, *args, **kwargs):
super(SignupForm, self).__init__(*args, **kwargs)
self.fields['first_name'].widget.attrs.update({'autofocus': 'autofocus'})
#remove labels for fields
for field_name in self.fields:
field = self.fields.get(field_name)
field.widget.attrs['placeholder'] = field.label
field.label =''
class Meta:
model = Profile
fields = ('first_name', 'last_name', 'gender', 'birthday', 'location')
def signup(self, request, user):
# Save your user
user.first_name = self.cleaned_data['first_name']
user.last_name = self.cleaned_data['last_name']
user.save()
# Save your profile
profile = Profile()
profile.user = user
profile.birthday = self.cleaned_data['birthday']
profile.location = self.cleaned_data['location']
profile.gender = self.cleaned_data['gender']
profile.save()
models.py
from django.db import models
from django.contrib.auth.models import User
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE, related_name='profile')
birthday = models.DateField(null=True, blank=True)
#first_name = models.CharField(max_length=100)
#last_name = models.CharField(max_length=100)
location = models.CharField(max_length=100)
timestamp = models.DateTimeField(auto_now_add= True, auto_now=False)
GENDER_CHOICES = (
('m', 'Male'),
('f', 'Female'),
)
# gender can take only one of the GENDER_CHOICES options
gender = models.CharField(max_length=1, choices=GENDER_CHOICES,
verbose_name='Gender')
def __str__(self):
return self.user.first_name
Rendered SignUp form
Maybe it is because you forgot adding
email = forms.EmailField(label='Email')
into the SignupForm fields?
also add 'email' into
fields = ('first_name', 'last_name', 'gender', 'birthday', 'location', 'email')
Related
I have two forms (OwnerCreateForm, EmployeesCreateForm) and 3 models (Profile, Company and Owner). when the owner signs up, it creates the company and its own User object. after owner login, you can create employees.
Have the Owner connect to the profile and associate it with the company
I need to associate the owning company to the employees.
That each company manages its users, that they see the same thing
Here are the details I'm using:
MODELS
class Profile(models.Model):
user = models.OneToOneField(User, null=True, on_delete=models.CASCADE)
image = models.ImageField(default='default.jpg', upload_to='profile_pics')
def __str__(self):
return '{} Profile'.format(self.user)
class Owner(models.Model):
profile = models.ForeignKey(Profile, on_delete=models.CASCADE)
def __str__(self):
return '{} Owner'.format(self.profile)
class Tienda(models.Model):
dueƱo = models.ForeignKey(Owner, null=True, on_delete=models.CASCADE)
nombre_tienda = models.CharField(verbose_name='Nombre de la Tienda', max_length=120)
direccion = models.CharField(verbose_name='Su Direccion', max_length=160)
phone = models.CharField(max_length=11, null=True)
businessemail = models.EmailField(unique = True, verbose_name='Su email')
def __str__(self):
return self.nombre_tienda
class Employee(models.Model):
STATUS = (
('Admin', 'Admin'),
('Gerente', 'Gerente'),
('Validador', 'Validador')
)
profile = models.ForeignKey(Profile, on_delete=models.CASCADE)
role = models.CharField(choices=STATUS, max_length=16)
tienda = models.ForeignKey(Tienda, null=True, on_delete=models.CASCADE)
def __str__(self):
texto = "{0} ({1}) {2}"
return texto.format(self.tienda, self.role, self.role)
FORMS
class TiendaForm(ModelForm):
class Meta:
model = Tienda
fields = ('nombre_tienda', 'direccion', 'businessemail')
class OwnerCreateForm(UserCreationForm):
class Meta:
fields = ('username', 'first_name', 'last_name', 'email', 'password1', 'password2')
model = User
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields['username'].label = 'Display Name'
self.fields['email'].label = "Email Address"
class EmployeesCreateForm(UserCreationForm):
is_admin = forms.BooleanField(required=False)
is_manager = forms.BooleanField(required=False)
is_systemAdmin = forms.BooleanField(required=False)
class Meta:
fields = ('username', 'first_name', 'last_name', 'email', 'password1', 'password2')
model = User
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields['username'].label = 'Display Name'
self.fields['email'].label = "Email Address"
VIEWS
def registroOwner(request):
if request.method == "POST":
form = OwnerCreateForm(request.POST)
tienda = TiendaForm(request.POST)
if form.is_valid() and tienda.is_valid():
tienda.save()
form.save()
messages.success(request, f'Tu cuenta ha sido creada!')
return redirect('login')
else:
form = OwnerCreateForm()
tienda = TiendaForm()
context = {
'title': 'Sign up Owner',
'form': form,
'tienda': tienda
}
return render(request, "accounts/signup.html", context)
I have a User model and a phone model the phone model has a foreign key relation with the user model I read the docs on NestedSerializers and tried it to no avail.
The model
class Phone(models.Model):
phone = models.CharField(
_("phone number"), max_length=13, blank=True, null=True)
otp = IntegerRangeField(min_value=6, max_value=6, blank=True, null=True)
def __str__(self):
return self.phone
class User(AbstractBaseUser, PermissionsMixin):
phone = models.ForeignKey(
Phone, on_delete=models.CASCADE, related_name="userphone", blank=False, null=True)
this is my serializers.py file
class PhoneSerializer(serializers.ModelSerializer):
# opt = serializers.IntegerField(read_only=True)
class Meta:
model = Phone
fields = ['phone']
class RegisterSerializerBase(serializers.ModelSerializer):
phone = PhoneSerializer(allow_null=True)
# otp = PhoneSerializer(many=True, read_only=True)
email = serializers.EmailField(
required=True,
validators=[UniqueValidator(queryset=User.objects.all())])
password = serializers.CharField(
write_only=True, re
quired=True, validators=[validate_password])
password2 = serializers.CharField(write_only=True, required=True)
class Meta:
model = User
fields = ('email', 'firstname', 'lastname', 'password', 'password2',
'phone',)
extra_kwargs = {'password': {'write_only': True},
'password2': {'write_only': True},
'firstname': {'required': True},
'lastname': {'required': True},
}
def validate(self, attrs):
if attrs['password'] != attrs['password2']:
raise serializers.ValidationError(
{"password": "Password fields didn't match."})
return attrs
def create(self, validated_data):
phones = validated_data.pop('phone')
instance = User.objects.create(
email=validated_data['email'],
firstname=validated_data['firstname'],
lastname=validated_data['lastname'],
is_active='True',
type=User.TYPES.OWNER,
)
instance.set_password(validated_data['password'])
for phone in phones:
Phone.objects.create(instance=instance, **phone)
instance.save()
return instance
when I go the the Browsable API and create a user with the credentials an error comes up saying
django.db.models.manager.BaseManager._get_queryset_methods.<locals>.create_method.<locals>.manager_method() argument after ** must be a mapping, not str
Check if this helps you -
Models -
User model is already defined.
class Phone(models.Model):
user = models.Foerienkey(User, related_name="abc")
phone = models.CharField(max_length=13, blank=True, null=True)
Serializer -
from rest_framework import serializers
from django.contrib.auth.models import User
class CurrentUserSerializer(serializers.Serializer):
abc = phoneserializer(many=True, required=False)
## define phone serializer before currentuser serializer
class Meta:
model = User
fields = ('username', 'email', 'id', 'abc')
Views -
##user create method
def create(self, validated_data):
phones = validated_data.pop('recievedPhoneDataArray')
instance = User.objects.create(
email=validated_data['email'],
firstname=validated_data['firstname'],
lastname=validated_data['lastname'],
is_active='True',
type=User.TYPES.OWNER,
)
instance.set_password(validated_data['password'])
for phone in phones:
Phone.objects.create(user=instance, **phone)
instance.save()
return instance
You will have to extend the registeruserserializer from rest frameowrk. may be.
I cannot update using an inline form.
I thought it was possible before, but it wasn't.
I'm trying to solve it, but it doesn't work.
I added.
I will post any other necessary items.
"Id
This field is required.
user
A Profile with this User already exists.
"
I got an error.
#view
class UserEdit(generic.UpdateView):
model = User
form_class = forms.UserUpdateForm
template_name = 'accounts/accounts_edit.html'
success_url = reverse_lazy('person:myaccount')
def get_object(self):
return get_object_or_404(User, pk=self.request.user.user_id)
#model
class User(AbstractBaseUser, PermissionsMixin):
username_validator = UnicodeUsernameValidator()
user_id = models.UUIDField(default=uuid_lib.uuid4,
primary_key=True, editable=False)
username = models.CharField(_('username'), unique=True, max_length=50,validators=[username_validator],error_messages={
'unique': _("A user with that username already exists."),
},)
class profile(models.Model):
image = models.ImageField(upload_to='profile/',default='profile/default.jpg')
first_name = models.CharField(_('first name'), max_length=30, blank=True,null=True)
last_name = models.CharField(_('last name'), max_length=150, blank=True,null=True)
birthday = models.DateField(_('birthday',),null=True)
user = models.OneToOneField(settings.AUTH_USER_MODEL, on_delete=models.CASCADE,)
#form
class ProfileUpdateForm(BaseModelForm):
class Meta:
model = profile
fields = ('first_name','last_name','birthday',)
ProfileFormSet = inlineformset_factory(User,profile,form=ProfileUpdateForm,extra=0)
class UserUpdateForm(mixins.ModelFormWithFormSetMixin,BaseModelForm):
formset_class = ProfileFormSet
class Meta:
model = User
fields = ('username','email',)
#mixin
class ModelFormWithFormSetMixin:
def __init__(self, *args, **kwargs):
super(ModelFormWithFormSetMixin, self).__init__(*args, **kwargs)
self.formset = self.formset_class(
instance=self.instance,
data=self.data if self.is_bound else None,
)
def is_valid(self):
return super(ModelFormWithFormSetMixin, self).is_valid() and self.formset.is_valid()
def save(self, commit=True):
saved_instance = super(ModelFormWithFormSetMixin, self).save(commit)
self.formset.save(commit)
return saved_instance
After creating a custom user model in my app, I have a studentProfile that inherits from the user model, which also contains avatar, semester, and dept_name. which works fine. However, when I was trying to display this studentProfile data using django-tables2, all rows keeps showing "-" and the ID been captured is from user model instead of studentProfile.
The weirdiest thing is i can get all the values from user model
correctly even when studentProfile is my table model for
django-tables2
I don't know what I am doing wrongly. Any help is really appreciated
my model definitions are as follow
class DepartmentData(models.Model):
fid = models.ForeignKey(FacultyData, on_delete=models.CASCADE)
dept_name = models.CharField(max_length=50)
created_on = models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.dept_name
class User(AbstractBaseUser):
# add additional fields here
user_id = models.CharField(max_length=15, unique=True)
first_name = models.CharField(max_length=30)
last_name = models.CharField(max_length=30)
active = models.BooleanField(default=True)# can login
staff = models.BooleanField(default=False) # staff user non superuser
admin = models.BooleanField(default=False) # superuser
USER_TYPE_CHOICES = (
(1, 'student'),
(2, 'lecturer'),
(3, 'bursary'),
(4, 'system'),
(5, 'admin'),
)
user_type = models.PositiveSmallIntegerField(choices=USER_TYPE_CHOICES)
USERNAME_FIELD = 'user_id'
REQUIRED_FIELDS = ['first_name', 'last_name', 'user_type']
objects = UserManager()
def __str__(self):
return self.user_id
def get_full_name(self):
return self.first_name + " " + self.last_name
def get_user_type(self):
return self.user_type
def has_perm(self, perm, obj=None):
return True
def has_module_perms(self, app_label):
return True
#property
def is_staff(self):
return self.staff
#property
def is_admin(self):
return self.admin
#property
def is_active(self):
return self.active
class StudentProfile(models.Model):
user = models.OneToOneField(User,on_delete=models.CASCADE)
semester = models.ForeignKey(SemesterData, on_delete=models.SET_NULL, null=True)
dept_name = models.ForeignKey(DepartmentData, on_delete=models.SET_NULL, null=True)
avatar = models.ImageField(upload_to='avatars/', null=True, blank=True)
def __str__(self):
return self.user.first_name
class SemesterData(models.Model):
sid = models.ForeignKey(SessionData, on_delete=models.CASCADE)
semester_name = models.CharField(max_length=50)
def __str__(self):
return self.semester_name
def current(self):
if SettingsData.objects.all().count():
st = SettingsData.objects.get(id=1)
if self.id == st.current_id:
return "Current Session-Semester"
else:
return format_html('{}', reverse('system:current_session_semester', args=[self.id]),
'Set Current')
else:
return format_html('{}', reverse('system:current_session_semester', args=[self.id]),
'Set Current')
here is my table.py
class StudentTable(tables.Table):
user_id = tables.Column(attrs = {'th': {'class': 'danger'}})
first_name = tables.Column(attrs = {'th': {'class': 'danger'}})
last_name = tables.Column(attrs = {'th': {'class': 'danger'}})
avatar = tables.Column(accessor ="user", verbose_name = "ass" )
active = tables.Column(attrs = {'th': {'class': 'danger'}})
last_login = tables.Column(attrs = {'th': {'class': 'danger'}})
edit_Action = tables.LinkColumn('system:semester_edit', text='Edit', args=[A('pk')],attrs={'a':{'class':'btn btn-info btn-sm'}, 'td':{'align': 'center'}, 'th': {'class': 'danger'}}, orderable=False)
class Meta:
model = StudentProfile
attrs = {'class':'table table-hover table-bordered table-responsive'}
sequence = ('user_id', 'first_name', 'last_name', 'avatar')
exclude = {'id', 'user', 'password', 'staff', 'admin'}
empty_text = _("There are no students yet")
template_name = 'django_tables2/bootstrap4.html'
I would love to get the department_name, semester_name as well as fields in the studentProfile which is serving as my table model
You are seeing empty values for all fields with your current configuration because you're trying to access fields user_id, first_name and last_name which are not fields of the StudentProfile model, but rather fields of the User model (to which StudentProfile is related by user field).
That being said, you should access those fields via the user relation, something like this:
class StudentTable(tables.Table):
user_id = tables.Column(accessor='user.user_id', ...)
first_name = tables.Column(accessor='user.first_name', ...)
last_name = tables.Column(accessor='user.last_name', ...)
...
As far as the DepartmentData and SemesterData relations go, I'm not sure why aren't they displayed by default, since they are fields of the StudentProfile model, and they aren't excluded via the exclude property on the Meta. You can maybe try to explicitly list them in the fields property and see if that helps.
2nd Screenshot of APIAPI Sample Screenshot
I'm New in Django, i want to help regarding validations in screenshot there is company_name, location, title and user_location fields except user info with proper validation
but i want to remove validations from company_name, location, title and user_location fields how to do?
Please find the above api screenshot and
Please find the below scripts,
views.py
class UserRegistrationView(generics.CreateAPIView):
"""
Register a new user.
"""
queryset = User.objects.all()
permission_classes = (permissions.AllowAny, )
def get_serializer_class(self, user_type=None):
if user_type == 'student':
return StudentRegistrationSerializer
return ProfessionalRegistrationSerializer
def post(self, request, user_type=None, format=None):
serializer_class = self.get_serializer_class(user_type)
serializer = serializer_class(data=request.data, context={'request': request})
if serializer.is_valid(raise_exception=True)
user = serializer.save(work_status=user_type)
token, created = Token.objects.get_or_create(user=user)
data = BasicUserSerializer(user, context={'request': request}).data
data.update({"token": token.key})
return Response(data)
serializes.py
class ProfessionalRegistrationSerializer(serializers.HyperlinkedModelSerializer):
password = serializers.CharField(max_length=20, write_only=True)
experiences = ExperienceSerializer(required=False)
email = serializers.EmailField()
first_name = serializers.CharField(max_length=30)
last_name = serializers.CharField(max_length=30)
class Meta:
model = User
fields = ('url', 'id', 'first_name', 'last_name', 'email', 'password',
'experiences', 'headline')
def validate_email(self, value):
from validate_email_address import validate_email
if User.all_objects.filter(email=value.lower()).exists():
raise serializers.ValidationError('User with this email already exists.')
# if not validate_email(value.lower(), check_mx=True):
# raise serializers.ValidationError('It looks like you may have entered an incorrect email address.')
return value.lower()
def create(self, validated_data):
experiences = validated_data.pop('experiences')
password = validated_data.pop('password')
email = validated_data.pop('email')
user = User.objects.create(
username=email.lower(),
email=email.lower(),
role_id=1)
user.set_password(password)
user.save()
user_location = experiences.pop('user_location')
if hasattr(user, 'location'):
user.location.location = user_location
user.save()
else:
UserLocation.objects.create(user=user, location=user_location)
Experience.objects.create(user=user)
return user
Another serializes.py for Experiance
class ExperienceSerializer(serializers.HyperlinkedModelSerializer):
user_location = LocationField()
location = LocationField()
class Meta:
model = Experience
fields = ('id', 'company_name', 'company', 'description', 'location',
'title', 'start_date', 'end_date', 'is_current', 'user_location')
I want to Remove Validation from company_name, company, description, location, title, start_date, end_date, user_location
actually these fields are second page means after complete the first step users move on second step so second step fields are optional
class ExperienceSerializer(serializers.HyperlinkedModelSerializer):
user_location = LocationField()
location = LocationField()
class Meta:
model = Experience
fields = ('id', 'company_name', 'company', 'description', 'location',
'title', 'start_date', 'end_date', 'is_current', 'user_location')
def create(self, validated_data):
return Experience.objects.create(field_a='value', field_b='value')
in the above class, what should be do to remove validation of
"error_msg": {
"location": [
"Expected a dictionary of items but got type \"str\"."
],
"start_date": [
"Date has wrong format. Use one of these formats instead: YYYY[-MM[-DD]]."
],
"end_date": [
"Date has wrong format. Use one of these formats instead: YYYY[-MM[-DD]]."
],
"user_location": [
"Expected a dictionary of items but got type \"str\"."
]
}
Experience Model
class Experience(models.Model):
"""
"""
user = models.ForeignKey(settings.AUTH_USER_MODEL, related_name='experiences')
company_name = models.CharField(max_length=200, db_index=True, blank=True)
company = models.ForeignKey('organisations.Organisation', null=True, blank=True, on_delete=models.SET_NULL)
description = models.TextField(null=True, blank=True)
location = models.ForeignKey('regions.Location', null=True, blank=True, on_delete=models.SET_NULL)
start_date = models.DateField(null=True, blank=True)
end_date = models.DateField(null=True, blank=True)
title = models.CharField(max_length=200, db_index=True, blank=True)
is_current = models.BooleanField(default=False)
is_associated = models.BooleanField(default=False)
created_at = models.DateTimeField(_('created at'), auto_now_add=True)
modified_at = models.DateTimeField(_('modified at'), auto_now=True)
class Meta:
db_table = 'experience'
verbose_name = _('experience')
verbose_name_plural = _('experiences')
ordering = ('-start_date',)
def __str__(self):
return getattr(self, 'title', '')
#property
def experience(self):
if self.end_date:
return (self.end_date - self.start_date).days
else:
return (datetime.datetime.now().date() - self.start_date).days
def get_formated_experience(self):
days = self.experience
total_months = round(days/30)
years = int(total_months/12)
months = round(((total_months/12)%1)*12)
year_txt = 'years' if years > 1 else 'year'
month_txt = 'months' if months > 1 else 'month'
return "%s %s %s %s" %(years, year_txt, months, month_txt)
Location Model
class Location(models.Model):
"""
"""
id = models.TextField(primary_key=True)
display_name = models.TextField(null=True, blank=True)
latitude = models.DecimalField(max_digits=15, decimal_places=10, null=True, blank=True)
longitude = models.DecimalField(max_digits=15, decimal_places=10, null=True, blank=True)
created_at = models.DateTimeField(auto_now_add=True)
objects = LocationManager()
You are getting Two types of validation error according to snapshot.
Field is required
Expected a dictionary and got a string
The required field error occurs when you have set field as required in your model. You can change this by adding blank=True in your model for that field.
For second error, your serializer is expecting a dictionary and you are sending a string. You can remove this validation by writing your custom create method.
class ExperienceSerializer(serializers.HyperlinkedModelSerializer):
user_location = LocationField()
location = LocationField()
class Meta:
model = Experience
fields = ('id', 'company_name', 'company', 'description', 'location',
'title', 'start_date', 'end_date', 'is_current', 'user_location')
def create(self, validated_data):
# you create code for that models.
Your seriailzers will be like this
class ProfessionalRegistrationSerializer(serializers.HyperlinkedModelSerializer):
password = serializers.CharField(max_length=20, write_only=True)
experiences = ExperienceSerializer(required=False)
email = serializers.EmailField()
first_name = serializers.CharField(max_length=30)
last_name = serializers.CharField(max_length=30)
class Meta:
model = User
fields = ('url', 'id', 'first_name', 'last_name', 'email', 'password',
'experiences', 'headline')
def validate_email(self, value):
from validate_email_address import validate_email
if User.all_objects.filter(email=value.lower()).exists():
raise serializers.ValidationError('User with this email already exists.')
# if not validate_email(value.lower(), check_mx=True):
# raise serializers.ValidationError('It looks like you may have entered an incorrect email address.')
return value.lower()
def create(self, validated_data):
experiences = validated_data.get('experiences')
password = validated_data.get('password')
email = validated_data.get('email')
user = User.objects.create(
username=email.lower(),
email=email.lower(),
role_id=1)
user.set_password(password)
user.save()
user_location = experiences.get('user_location')
location_object = None
if user_location:
location_object, created = Location.objects.get_or_create(display_name=user_location.get('display_name'), latitude= user_location.get('latitude'), longitude=user_location.get('longitude'))
user_experience = Experience.objects.create(user=user, company_name=experiences.get('company_name'), location=location_object)
return user
class ExperienceSerializer(serializers.HyperlinkedModelSerializer):
user_location = LocationField()
location = LocationField()
class Meta:
model = Experience
fields = ('id', 'company_name', 'company', 'description', 'location',
'title', 'start_date', 'end_date', 'is_current', 'user_location')