I have an member model with contains an email field. I recently realized that if a part of the email is capitalized, it won't show up in Django queries if I try to filter by the email (multiple member objects have the same email, but it may not be capitalized). I could have just made all emails lower-case when entering them into the database, but it's too late for that now (as the website is already launched). So how do I check who has a certain email, without being case sensitive?
Just use iexact:
User.objects.filter(email__iexact='email#email.com')
Case-insensitive exact match. If the value provided for comparison is None, it will be interpreted as an SQL NULL (see isnull for more details).
Member.objects.filter(email__iexact=email)
Related
recently, I started playing with Django and created a custom form for user registration. In that form to create the field for email I use something like
email = forms.EmailField()
I observed that address such as a#a.a is considered invalid by the form. Of course this is a nonsense email address. Nonetheless, I wonder how does Django checks for validity.
I found some topics on the net discussing how to check for validity of an email address but all of them were providing some custom ways. Couldn't find something talking about the django default validator.
In their docs on the email filed they specify
Uses EmailValidator to validate that the given value is a valid email address, using a moderately complex regular expression.
However that's not very specific so I decided to ask here.
For anyone also interested in this, I would suggest looking up the implementation (django.core.validators) as was kindly suggested by iklinac in the comments.
In it, there is not just the source but also mentions about standards that were used to derive regexes that check if domain and literal have valid format.
us should check docs here https://www.geeksforgeeks.org/emailfield-django-forms/#:~:text=EmailField%20in%20Django%20Forms%20is,max_length%20and%20min_length%20are%20provided.
if u wanna check validation use clean function like this :
from django.forms.fields import EmailField
email = EmailField()
my_email = "a#a.a"
print(email.clean(my_email))
if your email is valid then this func return value else return validation error
I'm reading Django Rest Framework documentation on router (https://www.django-rest-framework.org/api-guide/routers/) and encounter this:
^accounts/{pk}/$
I understand ^ means start of line, $ means end of line and everything but {pk}. What does it mean?
It means that an url pattern that includes a primary key, si valid. In the case of the documentation you are consulting, it means that the following url pattern is valid: accounts/121/. What SimpleRouter will do with it, is that urls that contain a primary key ({pk}), will be used to update or delete the accounts record with such primary key. In the example, account with primary key '121' would be retrieved, updated or deleted through such url.
This "variable_name" is received as a parameter by the view method or class method.
for my Django app i use PostgreSQL (9.3) and i want to use case insensitive text in my database. For this Popstgres has a 'new' extension named 'citext'.
As i understand it, django can't use this extension out of the box, so i have made an custom field:
class RsCharField(models.CharField):
...
def db_type(self, connection):
return 'citext'
I use a CharField as baseclass, because i still want all the django perks of being able to set a maximum length and the validators that come with that.
The database is created correctly and i end up with citext-tables:
description | citext | not null
But when i do a query, django translates te query to:
SELECT * FROM .... WHERE mytable.description::text LIKE 'TEST%'
which still is case sensitive. When i do a manual select and drop the ::text it works case-insensitive.
Question: What am i doing wrong, and how can i make my CharFields behave like case-insensitive fields in django when doing queries?
note: most importantly i want my indexes to behave like case insensitive indexes.
use the classes provided in django.contrib.postgres.fields.citext
https://docs.djangoproject.com/pt-br/1.11/_modules/django/contrib/postgres/fields/citext/
I am trying to add validation, inside my User model to validation emails using regex.
However, it's spits a dummy out at the first apostrophe.
'email' => 'required|regex:/^[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+#[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/',
Have you tried the 'email' validation rule?
'email' => 'required|email|unique:users,email'
http://laravel.com/docs/4.2/validation#rule-email
As the answer to this question on SO states, there is no simple regular expression to validate an email-address. Using your RegEx could maybe catch valid addresses (although that's just speculation of mine). Using the email-validation-rule would be my first choice.
But you are right, this is just the server side in the first place, if you ignore redirecting users back with input and error messages..
On the client-side, you would have some options. The first one would be to simply rely on the build in browser-validation, by declaring the corresponding input-field as an email-address which you should do anyway:
{{ Form::email($name, $value = null, $attributes = array()) }}
Another, more advanced way would be to create some kind of helper to check the typed input via Ajax using the same validation rule and returning the error messages or sth. similar. This could be an additional route to your Model-Resource for example. This way, you would be stable and consistent.
Before somebody marks this question as a duplicate of this question Can django's auth_user.username be varchar(75)? How could that be done? or other such questions on SO, please read this question. The question I linked to asks this question precisely but unfortunately the answers don't address the question that was asked.
Can I change the auth_user.username field to be 100 characters long by doing the following:
Run ALTER table in DB for the username field
Change the max_length here: username = models.CharField(_('username'), max_length=30, unique=True, help_text=_("Required. 30 characters or fewer. Letters, numbers and #/./+/-/_ characters"))
Would it break anything in Django if I were to do this?
That this will break when I update Django to a higher version is not a problem. I'm also not looking at writing other authentication methods.I just want to know if I would break anything if I were to do this.
You need to monkey-patch max-length in several places: model-field's description, form-field's description and max-length validators. Max-length validators are attached to form-fields as well as model-fields.
Here is a code snippet, which will patch everything:
https://gist.github.com/1143957 (tested with django 1.2 and 1.3)
Update:
Good news! Since django 1.5 you can override user model: Customizing the User model
There is no harm in doing that.
Just change the length in the model and in the database :)
Create a user profile model, add your very-long-username field there, and use it. of course this renders the genuine username field useless, but it is much better than hacking Django code, which will get you into trouble when you need to upgrade it.
For me, the code below works and is simple well.
from django.contrib.auth.models import AbstractUser
class MyUser(AbstractUser):
....
# your custom fields
MyUser._meta.get_field('username').max_length = 255 # or 100
after you can run your migration
If you change the database manually as well as the model accordingly then there should be no problem.
You can also change back otherwise, and I would say make a backup just in case but I'm not sure its even necessary
for future needs this is the best and easiest way i found out:
https://github.com/GoodCloud/django-longer-username
Another solution is to change your authentication code. When a new user signs up, they enter an email, you save this in the email field so you have it, and if their email is >30 characters, you shorten it before putting it into the user field. Then, change your login authentication for new logins.