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

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.

Related

How to extend search record to also look at custom Many2Many field(s)?

In this image, there is a product search record that will search for name and default_code. I need to make it so that it will also look at my custom Many2Many field.
This is the field in the inherited model.
product_list = fields.Many2many("product.list", string="Product List")
The custom model only has _name, _description, and name variables.
The question is how to make the search to also look at all of the possible Many2Many data of this field.
I have tried this in the inherited model:
#api.model
def name_search(self, name='', args=None, operator='ilike', limit=100):
res = super(product_template_inherit, self).name_search(name='', args=None, operator='ilike', limit=100)
ids = self.search(args + [(name, 'in', 'product_list.name')], limit=limit)
if ids:
return ids.name_get()
return res
Nothing happens to the search. It still searches using the same behavior regardless of the code above.
Summary: I need to be able to search product by product list (custom Many2Many field inherited in the product.template model)
=============================================
UPDATE
Current code from what I have been trying is now this.
#api.model
def _name_search(self, name, args=None, operator='ilike', limit=100, name_get_uid=None):
args = args or []
if operator == 'ilike' and not (name or '').strip():
domain = []
else:
domain = ['|', ('name', 'ilike', name), ('product_list.name', 'ilike', name)]
product_ids = self._search(expression.AND([domain, args]), limit=limit, access_rights_uid=name_get_uid)
return self.browse(product_ids).name_get()
However, it looks like it still searches using the same old fields. It does not change to behave as my function is written.
You can compute the search domain then return the result of the _search method.
The fleet module already uses the same logic to search vehicles using the driver name, you have just to replace the driver_id with product_list:
class ProductProduct(models.Model):
_inherit = 'product.product'
#api.model
def _name_search(self, name, args=None, operator='ilike', limit=100, name_get_uid=None):
args = args or []
if operator == 'ilike' and not (name or '').strip():
domain = []
else:
domain = ['|', ('name', operator, name), ('product_list.name', operator, name)]
return self._search(expression.AND([domain, args]), limit=limit, access_rights_uid=name_get_uid)

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

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.

SQL Query logic to Django ORM Query logic

I have tried to think about how the following SQL query would be structured as a Django ORM query but I have had no luck in my multiple attempts. Can anyone help?
SELECT targets_genetarget.gene, count(targets_targetprediction.gene) as total
FROM targets_genetarget
LEFT OUTER JOIN targets_targetprediction on targets_targetprediction.gene =
targets_genetarget.gene
WHERE list_name LIKE %s
GROUP BY targets_genetarget.gene
class GeneTarget(models.Model):
list_name = models.CharField(max_length=100)
gene = models.CharField(max_length=50)
date_added = models.DateField(auto_now=True)
class Meta:
unique_together = (('list_name', 'gene'),)
def __str__(self):
return self.list_name
class TargetPrediction(models.Model):
specimen_id = models.CharField(max_length=100)
patient_peptide = models.ForeignKey(Peptide, on_delete=models.CASCADE, verbose_name="Peptide", related_name="predictions")
allele = models.ForeignKey(Allele, on_delete=models.CASCADE, verbose_name="Allele", related_name="predictions")
gene = models.CharField(max_length=50)
class Meta:
unique_together = (('specimen_id', 'patient_peptide', 'allele', 'gene'),)
def get_absolute_url(self):
return f'/samples/specid-{self.specimen_id}'
def __str__(self):
return (f'Specimen: {self.specimen_id} Peptide: {self.patient_peptide} Allele: {self.allele} Gene: {self.gene} ')
There's nothing stopping you declaring the TargetPrediction.gene field as a foreign key using the to_field attribute, so you wouldn't need to change the data at all:
class TargetPrediction(models.Model):
...
gene = models.ForeignKey("GeneTarget", to_field="gene")
Now your query simply becomes:
GeneTarget.objects.filter(list_name="whatever").values("gene").annotate(total=Count("targetprediction"))

_sql_constraints not working in Odoo v10

I have a model defined as-
class ModelName(models.Model):
_name = 'model_name'
student_id = fields.Many2one('op.student', 'Student')
I want that student should be unique. So i added -
_sql_constraints = [
('student_unique',
'UNIQUE(student_id)', 'Some message!')
]
but it's not doing anything. I can still select same student and save the form.
I want when i click create button, students for which record has already been saved should not be shown.
What can i do to achieve this??
Try this below domain function in your field, I'm sure you will get your required output.
student_id = fields.Many2one('op.student',domain=lambda self: self.get_not_existing_student_id(), string='Student')
#api.model
def get_not_existing_student_id(self):
self.env.cr.execute("select id from op_student where id not in (select student_id from model_name)")
datas = self.env.cr.fetchall()
student_ids = []
for record in datas:
student_ids.append(record[0])
return [('id','in',student_ids)]
Other Way:
student_id = fields.Many2one('op.student',string='Student')
put it in a view like:
<field name="student_id" context="{'find_existed':1}" options="{'no_create':1}"/>
Then inherit the method name_get() in op.student model like this.
class op_student(models.Model):
_inherit ="op.student"
#api.multi
def name_get(self):
if self._context.get("find_existed",False):
self.env.cr.execute("select id from op_student where id not in (select student_id from model_name)")
datas = self.env.cr.fetchall()
student_ids = []
for record in datas:
student_ids.append(record[0])
for student in self:
if student in student_ids:
res.append((student.id,student.name))
else:
res=super(op_student,self).name_get()
return res

Django Rest Framework - Could not resolve URL for hyperlinked relationship using view name "field-detail"

I know that this inconvenient is very presented, may be that I need learn more about of serializer relationships
I have the following model:
class Field(models.Model):
FIELD_TYPE_NATURE = 'Grama natural'
FIELD_TYPE_ARTIFICIAL = 'Grama sintetica'
FIELD_TYPE_CHOICES = (
(FIELD_TYPE_NATURE, u'Grama natural'),
(FIELD_TYPE_ARTIFICIAL, u'Grama sintetica'),
)
MODALITY_11 = 'Fútbol 11'
MODALITY_8 = 'Fútbol 8'
MODALITY_CHOICES = (
(MODALITY_11, u'Fútbol 11'),
(MODALITY_8, u'Fútbol 8'),
)
name = models.CharField(
max_length=150,
unique=True,
db_index=True,
primary_key=True,
)
field_type = models.CharField(
choices=FIELD_TYPE_CHOICES,
default=False,
blank=False,
max_length=20,
verbose_name=('Tipo de material/grama de la cancha')
)
modality = models.CharField(
max_length=40,
blank=False,
verbose_name='Modalidad'
)
photo = models.ImageField(upload_to='fields', blank=True, null=True)
location = models.CharField(max_length=150, blank=False)
def __str__(self):
return '%s %s %s' % (self.name, self.field_type, self.location)
My serializer is the following:
class FieldSerializer(serializers.HyperlinkedModelSerializer):
#url = serializers.HyperlinkedIdentityField(view_name='field-detail',)
class Meta:
model = Field
fields = ('url', 'name','field_type','modality','photo','location')
My viewset is:
class FieldViewSet(viewsets.ModelViewSet):
queryset = Field.objects.all()
serializer_class = FieldSerializer
This is my router:
router = routers.DefaultRouter()
router.register(r'fields', FieldViewSet)
And my url:
...
url(r'^api/', include(router.urls)),
...
When I go to the http://localhost:8000/api/fields/ url I get the following message:
File "/home/bgarcial/.virtualenvs/fuupbol2/lib/python3.5/site-packages/rest_framework/relations.py", line 386, in to_representation
raise ImproperlyConfigured(msg % self.view_name)
django.core.exceptions.ImproperlyConfigured: Could not resolve URL for **hyperlinked relationship using view name "field-detail". You may have failed to include the related model in your API, or incorrectly configured the `lookup_field` attribute on this field.**
[11/Nov/2016 16:39:53] "GET /api/fields/ HTTP/1.1" 500 187477
When I use HyperlinkedIdentityField in my FieldSerializer class:
class FieldSerializer(serializers.HyperlinkedModelSerializer):
url = serializers.HyperlinkedIdentityField(view_name='field-detail',)
class Meta:
model = Field
fields = ('url', 'name','field_type','modality','photo','location')
I follow getting the same error.
Althought when I go to the url http://localhost:8000/api/fields/ I want get is a list of my objects, then is possible that I should put:
url = serializers.HyperlinkedIdentityField(view_name='field-list',)
?
I use HyperlinkedIdentityField according to:
This field can be applied as an identity relationship, such as the
'url' field on a HyperlinkedModelSerializer. It can also be used for
an attribute on the object.
I put the field-list in my view_name attribute and I get the error related
Could not resolve URL for hyperlinked relationship using view name "field-list". You may have failed to include the related model in your API, or incorrectly configured the `lookup_field` attribute on this field.
I don't understand the situations when I should use view_name attribute in relation to if I wnt get a list objects, a object detail and so ... although here explain something about it.
When I should use HyperlinkedModelSerializer and ModelSerializer