Name Error at /registration/api/registration/ name 'name' is not defined - serialization

Actually, I am trying to validate the fields which are given in serializers
Server time: Thu, 24 Dec 2020 11:29:07 +0000
Note: Issue is in the validation fields.
It was working fine before adding the validation fields.
Can someone help me in solving the issue?
I thought validation is so easy but I got the following issues.
my serializers.py:
from rest_framework.response import Response
from rest_framework import serializers
from rest_framework.exceptions import ValidationError
from django.utils.translation import ugettext_lazy as _
from users.models import SuperUser
class RegistrationSerializer(serializers.Serializer):
email = serializers.EmailField(max_length=200)
name = serializers.CharField( max_length=200)
first_name = serializers.CharField( max_length=200)
last_name = serializers.CharField( max_length=200)
phone = serializers.IntegerField()
country = serializers.CharField( max_length=300)
state = serializers.CharField( max_length=100)
city = serializers.CharField(max_length=100)
zip_code = serializers.IntegerField()
password = serializers.CharField(style={'input_type': 'password'}, write_only = True)
confirm_password = serializers.CharField(style={'input_type': 'password'}, write_only = True)
def validate_email(self, value):
"""
Check that the email is provided by the user or not.
"""
if '#gmail.com' not in value.lower():
raise serializers.ValidationError("your email is not correct")
return value
def validate_name(self, value):
"""
Check that the name is provided by the user or not.
"""
if name not in value.lower():
raise serializers.ValidationError("This field may not be empty")
return value
def validate_first_name(self, value):
"""
Check that the first_name is provided by the user or not.
"""
if first_name not in value.lower():
raise serializers.ValidationError("This field may not be empty")
return value
def validate_last_name(self, value):
"""
Check that the last_name is provided by the user or not.
"""
if last_name not in value.lower():
raise serializers.ValidationError("This field may not be empty")
return value
def validate_phone(self, value):
"""
Check that the phone is provided by the user or not.
"""
if phone not in value:
raise serializers.ValidationError("This field may not be empty")
return value
def validate_country(self, value):
"""
Check that the country is provided by the user or not.
"""
if country not in value.lower():
raise serializers.ValidationError("This field may not be empty")
return value
def validate_state(self, value):
"""
Check that the state is provided by the user or not.
"""
if state not in value.lower():
raise serializers.ValidationError("This field may not be empty")
return value
def validate_city(self, value):
"""
Check that the city is provided by the user or not.
"""
if city not in value.lower():
raise serializers.ValidationError("This field may not be empty")
return value
def validate_zip_code(self, value):
"""
Check that the zip_code is provided by the user or not.
"""
if zip_code not in value:
raise serializers.ValidationError("This field may not be empty")
return value
def save(self):
account = SuperUser(
email = self.validated_data['email'],
name = self.validated_data['name'],
first_name = self.validated_data['first_name'],
last_name = self.validated_data['last_name'],
phone = self.validated_data['phone'],
country = self.validated_data['country'],
state = self.validated_data['state'],
city = self.validated_data['city'],
zip_code = self.validated_data['zip_code'],
)
password = self.validated_data['password']
confirm_password = self.validated_data['confirm_password']
if password != confirm_password:
raise ValidationError(_("Both passwords doesn't match"))
account.set_password(password)
account.save()
return account
my models.py:
from django.db import models
from django.contrib.auth.base_user import AbstractBaseUser, BaseUserManager
from django.contrib.auth.models import AbstractUser
from django.contrib.auth.models import PermissionsMixin
from django.utils.translation import ugettext_lazy as _
from django.db.models.signals import post_save
from django.dispatch import receiver
from rest_framework.authtoken.models import Token
from django.conf import settings
# Create your models here.
class CustomUser(BaseUserManager):
"""
Custom user model manager where email is the Unique identifier
for authentication instead of username.
"""
def _create_user(self, email, password, **extra_fields):
"""
Create and save a User with the given email and password.
"""
if not email:
raise ValueError(_('Email must be provided.'))
if not password:
raise ValueError(_('Password must be provided.'))
email = self.normalize_email(email) # normalize_email is used to validate the given email.
user = self.model(email=email, **extra_fields)
user.set_password(password)
user.save(using=self._db)
return user
def create_user(self, email, password = None, **extra_fields):
extra_fields.setdefault('is_superuser', False)
extra_fields.setdefault('is_staff', False)
extra_fields.setdefault('is_active', True)
return self._create_user(email, password, **extra_fields)
def create_superuser(self, email, password, **extra_fields):
'''
It will create a superuser with the given email and password
'''
extra_fields.setdefault('is_superuser', True)
return self._create_user(email, password, **extra_fields)
class SuperUser(AbstractBaseUser, PermissionsMixin):
"""docstring for ClassName"""
username = None
email = models.EmailField(_('Email Address'), unique=True)
name = models.CharField(_('Full Name'), blank=True, max_length=200)
first_name = models.CharField(_('first Name'), blank=True, max_length=200)
last_name = models.CharField(_('last Name'), blank=True, max_length=200)
phone = models.IntegerField(_('phone'), blank=True, default=False)
country = models.CharField(_('country'), blank=True, max_length=300)
state = models.CharField(_('state'), blank=True, max_length=100)
city = models.CharField(_('city'), blank=True,max_length=100, default=False)
zip_code = models.IntegerField(_('zip-code'), blank=True, default=False)
is_staff = models.BooleanField(_('is_staff'), default=True)
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = ['name', 'first_name', 'last_name', 'phone','country', 'state', 'city', 'zip_code']
objects= CustomUser()
class Meta:
verbose_name = 'User'
verbose_name_plural = 'Users'
def __str__(self):
return self.email
#receiver(post_save, sender=settings.AUTH_USER_MODEL)
def token_creation(sender, instance=None, created=False, **kwargs):
if created:
Token.objects.create(user=instance)
I am getting this error :
NameError at /registration/api/registration/
name 'name' is not defined
Request Method: POST
Request URL: http://127.0.0.1:8000/registration/api/registration/
Django Version: 3.1.4
Exception Type: NameError
Exception Value:
name 'name' is not defined
Exception Location: C:\Users\Royal\Desktop\eign-project\eign_project\users\serializers.py, line 36, in validate_name
Python Executable: C:\Users\Royal\Desktop\eign-project\venv\Scripts\python.exe
Python Version: 3.9.0
Python Path:
['C:\\Users\\Royal\\Desktop\\eign-project\\eign_project',
'C:\\Users\\Royal\\AppData\\Local\\Programs\\Python\\Python39\\python39.zip',
'C:\\Users\\Royal\\AppData\\Local\\Programs\\Python\\Python39\\DLLs',
'C:\\Users\\Royal\\AppData\\Local\\Programs\\Python\\Python39\\lib',
'C:\\Users\\Royal\\AppData\\Local\\Programs\\Python\\Python39',
'C:\\Users\\Royal\\Desktop\\eign-project\\venv',
'C:\\Users\\Royal\\Desktop\\eign-project\\venv\\lib\\site-packages']

I got an answer by simply adding some functionalities due to which validation worked fine for me.
def validate_first_name(self, value):
"""
Check that the first_name is provided by the user or not.
"""
name = self.get_initial()
first_name = name.get('first_name')
if first_name not in value.lower():
raise serializers.ValidationError("This field may not be empty")
return value
and same logic can be applied to other validation fields.

Related

Update records on one2many fields in wizard for odoo16

Geting Issue 'TypeError: unhashable type: 'dict' for insert values in one2many field from onchange method in odoo16
My code is below:
class EmployeeAddWizard(models.TransientModel):
_name = 'employee.add.wizard'
line_ids = fields.One2many('employee.goal.add.line', 'wizard_id', string="Lines")
#api.onchange('challenge_id', 'employee_id')
def _onchange_action_goal_add(self):
r = []
value = {}
self.line_ids = {}
if self.challenge_id and self.employee_id:
goal_records = self.env['gamification.challenge.line'].search([('challenge_id', '=', self.challenge_id.id)])
for emp in self.employee_id:
for line in goal_records:
data = {'wizard_id': self.id, # Other table m2o
'goal_definition_id': line.definition_id.id,
'goal_rating': 0.0,
'goal_target': line.target_goal,
'employee_id': emp.id,
}
r.append(data)
value.update(records=r)
self.line_ids = value['records']
class GoalLine(models.Model):
_name = 'employee.goal.add.line'
wizard_id = fields.Integer()
goal_definition_id = fields.Many2one('gamification.goal.definition', string='Goal Definition', required=True, ondelete="cascade")
goal_rating = fields.Float('Rating', required=True)
goal_target = fields.Float('Target Value ', required=True)
employee_id = fields.Many2one('res.users', string="Employee", required=True, ondelete="cascade")
Thanks in advance
You passed a list of dicts which is not valid, you need to use special commands
Example:
r.append(Command.create(data))
or:
r.append((0, 0, data))
You can use Command.clear(), to remove previous lines if needed ( self.line_ids = {} should raise an error: ValueError: Wrong value).
Check this answer

Django Rest Framework getting Bad Request:400 error with serializer errors that I thought I took care of but I can't figure out where I went wrong?

I am trying to make a post request through insomnia to create a snake instance, but I am getting a Bad Request:400 error. I printed the serializer errors and got this:
{
'owner': [ErrorDetail(string='Incorrect type. Expected URL string, received ReturnDict.', code='incorrect_type')],
'birthday': [ErrorDetail(string='This field is required.', code='required')],
'date_aquired': [ErrorDetail(string='This field is required.', code='required')],
'species': [ErrorDetail(string='Incorrect type. Expected URL string, received ReturnDict.', code='incorrect_type')],
'breeder_id': [ErrorDetail(string='This field is required.', code='required')],
'mother': [ErrorDetail(string='This field is required.', code='required')],
'father': [ErrorDetail(string='This field is required.', code='required')]
}
Here is my serializer which I thought would take care of the null/blank fields:
class SnakeDetailSerializer(serializers.HyperlinkedModelSerializer):
href = serializers.HyperlinkedIdentityField(view_name="api_species_detail")
birthday = serializers.DateField(allow_null=True)
date_aquired = serializers.DateField(allow_null=True)
enclosure_id = serializers.CharField(allow_null=True, allow_blank=True)
breeder_id = serializers.CharField(allow_null=True, allow_blank=True)
father = serializers.CharField(allow_null=True, allow_blank=True)
mother = serializers.CharField(allow_null=True, allow_blank=True)
class Meta:
model = Snake
fields = [
'href',
'id',
'owner',
'name',
'age',
'birthday',
'date_aquired',
'gender',
'status',
'weight',
'enclosure_id',
'species',
'is_cbb',
'is_imported',
'breeder_id',
'mother',
'father'
]
Here is my model:
class Snake(models.Model):
# BASIC INFO
owner = models.ForeignKey(settings.AUTH_USER_MODEL,
related_name="collection",
on_delete=models.CASCADE
)
STATUS_CHOICES = (
('Active', 'Active'),
('Deceased', 'Deceased'),
('Quarantine', 'Quarantine'),
('For Sale', 'For Sale'),
('On Loan', 'On Loan'),
('Reserved', 'Reserved'),
('Sold', 'Sold')
)
GENDER_CHOICES = (
('M', 'Male'),
('F', 'Female'),
('NA', 'Unknown')
)
name = models.CharField(max_length=255)
age = models.SmallIntegerField()
birthday = models.DateField(null=True, blank=True)
date_aquired = models.DateField(null=True, blank=True)
status = models.CharField(max_length=10, choices=STATUS_CHOICES)
gender = models.CharField(max_length=2, choices=GENDER_CHOICES)
weight = models.DecimalField(max_digits=10, decimal_places=2)
enclosure_id = models.CharField(max_length=255, null=True, blank=True)
# SPECIES INFO
species = models.ForeignKey(SpeciesInfo, related_name="snakes", on_delete=models.PROTECT)
# LINEAGE INFO
is_cbb = models.BooleanField(default=False)
is_imported = models.BooleanField(default=False)
breeder_id = models.CharField(max_length=255, null=True, blank=True)
mother = models.CharField(max_length=255, null=True, blank=True)
father = models.CharField(max_length=255, null=True, blank=True)
here is my view:
#api_view(['GET', 'POST'])
def api_list_snakes(request):
if request.method == 'GET':
snakes = Snake.objects.all()
serializer = SnakeListSerializer(snakes, many=True)
return Response(
{'snakes': serializer.data}
)
else:
data = JSONParser().parse(request)
# print(data)
species = SpeciesInfo.objects.get(id=data["species"])
species_serialized = SpeciesInfoSerializer(species, context={'request':request})
owner = GetUserSerializer(request.user)
data['owner'] = owner.data
data["species"] = species_serialized.data
serializer = SnakeDetailSerializer(data=data, context={'request':request})
if serializer.is_valid():
serializer.save()
return Response(serializer.data, status=201)
print(serializer.errors)
return Response(serializer.data, status=400)
I have also added a photo of the insomnia request.insomnia_request
I thought adding the allow_null and allow_blank on the fields would correct the bad request error but it doesn't seem to have changed anything I am also getting errors for my foreign key fields and I am not sure why?
Help would be very much appreciated! Thanks!
I tried to add the fields that were allowed to be blank/null to the serializer here:
class SnakeDetailSerializer(serializers.HyperlinkedModelSerializer):
href = serializers.HyperlinkedIdentityField(view_name="api_species_detail")
birthday = serializers.DateField(allow_null=True)
date_aquired = serializers.DateField(allow_null=True)
enclosure_id = serializers.CharField(allow_null=True, allow_blank=True)
breeder_id = serializers.CharField(allow_null=True, allow_blank=True)
father = serializers.CharField(allow_null=True, allow_blank=True)
mother = serializers.CharField(allow_null=True, allow_blank=True)
and I expected that to correct the errors saying that they were required fields but they did not.
I also thought I had corrected the Foreign Key issues but it says they are expected a url string? I was using the id and it is getting the correct one so I'm not sure why it is mad about it
I figured out how to fix my required field error. I had to add required=True to the serializer fields but I still can't get the foreign keys to work

How to check if a record already exists or not in database in DRF?

I am working on DRF. I am creating an API of POST request that overriding its features. I want to add one functionality if a particular field value already exists in DB then, user cannot create post request and instead of it getting a message that he couldn't do it.
views.py
class PizzaOrderViewSet(viewsets.ModelViewSet):
http_method_names = ['get', 'put', 'patch', 'post']
def create(self, request, *args, **kwargs):
data = request.data
order = PizzaOrder.objects.create(
name=data['name'], flavours=data['flavours'],
number=data['number'], size=data['size'],
customer_name=data['customer_name'],
customer_address=data['customer_address']
)
order.save()
serializer = PizzaOrderSerializer(order)
return Response(serializer.data)
serializers.py
class PizzaOrderSerializer(serializers.ModelSerializer):
class Meta:
model = PizzaOrder
validators = [
UniqueTogetherValidator(
queryset=PizzaOrder.objects.all(),
fields=['name', 'flavours', 'size', 'customer_name', 'customer_address'],
message='This field should be unique'
)
]
models.py
from django.db import models
from datetime import datetime
FLAVOURS_CHOICE = (
('Margarita', 'Margarita'),
('Marinara', 'Marinara'),
('Salami', 'Salami'),
)
SIZE_CHOICE = (
('Small', 'Small'),
('Medium', 'Medium'),
('Large', 'Large'),
)
STATUS_CHOICE = (
('Open', 'Open'),
('Accepted', 'Accepted'),
('Preparing', 'Preparing'),
('OnWay', 'OnWay'),
('Delivered', 'Delivered'),
)
class PizzaOrder(models.Model):
name = models.CharField(max_length=50, blank=False)
flavours = models.CharField(max_length=20, choices=FLAVOURS_CHOICE)
quantity = models.IntegerField()
size = models.CharField(max_length=10, choices=SIZE_CHOICE)
customer_name = models.CharField(max_length=30, blank=False)
customer_address = models.TextField(blank=False)
ordered_time = models.DateTimeField(default=datetime.now, editable=False)
status = models.CharField(max_length=20, choices=STATUS_CHOICE, default='Open')
def __str__(self):
return self.name
class Meta:
ordering = ['-ordered_time']
unique_together = ('name', 'flavours', 'quantity', 'size')
How could I achieve this?

odoo program add mail follower no default subtype

class jj_loan(models.Model):
_name = 'jj_loan.jj_loan'
name = fields.Char(required=True)
_inherit = ['mail.thread', 'ir.needaction_mixin']
state = fields.Selection([('Draft','Draft'),('Apply','Apply')] ,default="Draft")
manager_id = fields.Many2one('hr.employee', 'Approval',default=_supervisor_get)
def add_approve_follower(self):
vals={}
partner_id = []
ptn = self.env['res.partner'].search([('email', '=', self.manager_id.user_id.email)]) //get partner id by email
if not ptn:return vals //if get fail return {}
for x in self.message_follower_ids:
if x.partner_id.id == ptn.id:return vals //if already added in followers return {}
partner_id.append(ptn.id)
vals['message_follower_ids'] = [(0,0,{
'res_model':'jj_loan.jj_loan',
'partner_id':pid}) for pid in partner_id]
return vals; //return message_follower_ids
#api.one
def jj_loan_aprrove(self):
vals = self.add_account_follower(); //get now followers
vals['state'] = 'Approve'
self.write(vals)
self.send_followers( _("Approved") )
return True
#api.multi
def send_followers(self,body):
followers = [x.partner_id.id for x in self.message_follower_ids]
self.message_post(body=body,type="notification",subtype="mt_comment",parnter_ids=followers)
return True
when jj_loan_aprrove button clicked , manager_id is automatically added into the follower list, but ,when message created ,the manager can not get notification. and then I found this caused as bellowes:
I want to know how to add followers programmely and make the default checkbox checked
thanks
finally, after read the odoo default addons mail, I found message_follower_ids should have key for res_model so the solution for this question is :
default_subtypes = self.env['mail.message.subtype'].search([ ('default', '=', True), '|', ('res_model', '=', model_id), ('res_model', '=', False)])
vals['message_follower_ids'] = [(0,0,{
'res_model':model_id,
'subtype_ids': [(6, 0, default_subtypes.ids)],
'partner_id':pid}) for pid in partner_id]
return vals;

Django auth.models.User query by full name but Chinese name

In Chinese, the name format is 'LastnameFirstname' (number of characters for both Lastname and Firstname are varied), while in English, it is 'Firstname LastName'. We can see that in Chinese, the first name last name is swapped (which is not a problem in query here), and the first name last name is NOT separated by whitespace (which caused me this problem).
In SQL, we can do this:
SELECT *
FROM USER
WHERE Concat(last_name, first_name) = 'LastnameFirstName';
But how can I do this in Django? Given a FULLNAME string as 'LastnameFirstname', how can I do:
User.objects.filter(last_name+firstname=FULLNAME)
Another solution is to create a custom User model and create a new field called "full name", but this solution disables me to use other django built-in functions:
class User( models.Model ):
first_name = models.CharField( max_length=64 )
last_name = models.CharField( max_length=64 )
full_name = models.CharField( max_length=128 )
def save( self, *args, **kw ):
self.full_name = '{0}{1}'.format( first_name, last_name )
super( User, self ).save( *args, **kw )
I guess there would be a better solution.
Thanks. :)
You can either link to the User model and create your own class:
class UserProfile(models.Model):
user = models.OneToOneField(settings.AUTH_USER_MODEL)
def full_name(self):
return self.user.last_name + self.user.first_name
....
or you could subclass the AbstractUser model to define your own custom user attributes there:
from django.contrib.auth.models import AbstractUser
class MyUser(AbstractUser):
first_name = models.CharField(max_length=30)
last_name = models.CharField(max_length=30)
def full_name(self):
return self.last_name + self.first_name
Then in your settings set the default user model to your new class:
AUTH_USER_MODEL = 'myapp.MyUser'
The AbstractUser model only has 3 attributes: password,last_login and is_active. You can define the rest yourself.