Django Field Regex Validation - regex

I am trying to create a model to store an hashtag.
The validator doesn't seem to be working, making the field accept all inputs, and I can't find the solution.
Here is my model:
class Hashtags(models.Model):
hashtag_validator = RegexValidator(r'^[#](\w+)$', "Hashtag doesn't comply.")
hashtag_id = models.AutoField(primary_key=True)
hashtag_text = models.CharField(max_length=100, validators=[hashtag_validator], unique=True)
def get_id(self):
return self.hashtag_id
def get_text(self):
return self.hashtag_text

You can alter it to the below given code to see it working
hashtag_validator = CharField(
max_length=50,
required=True, #if you want that field to be mandatory
validators=[
RegexValidator(
regex='^[#](\w+)$',
message='Hashtag doesnt comply',
),
]
)
Hope that helps!!
If that is causing problem you can try writing your own validator
from django.core.exceptions import ValidationError
import re
def validate_hash(value):
reg = re.compile('^[#](\w+)$')
if not reg.match(value) :
raise ValidationError(u'%s hashtag doesnot comply' % value)
and change your model field to
hashtag_validator = models.Charfield(validators=[validate_hash])

Very late to the party so I doubt that this is still a problem for OP, but I will leave this here just for posterity and people that happen to come across this post. Probably you are instantiating and saving an object directly, e.g Hashtags(hashtag_text='invalid-tag').save(). This will not call the validators. The validators are only called when full_clean or clean is called, which is only done automatically if you go through a ModelForm. If you instantiate objects manually, either through the constructor or the object collection Hashtags.objects.create the validators will not be called.

In addition to S.Ali answer:
based on example from here
def uncvalidator(value):
"""Custom UNC path validator"""
import re
from django.utils.translation import gettext_lazy as _
UNC_REGEX = r'^local.company/some/share'
regex = re.compile(UNC_REGEX, re.IGNORECASE)
if not regex.match(value):
raise ValidationError(
_('Entered path %(value)s is incorrect.'),
params={'value': value},
)
unc = models.CharField(
validators=[uncvalidator],
)

Related

Duplicate UUID if we enter a new input from html?

getting error- i saved one form from html into my database
while when i tried saving the next it gave me this error-
IntegrityError at customer
(1062, "Duplicate entry 'ad138e46-edc0-11va-b065-a41g7252ecb4'' for key 'customer.PRIMARY'")
kindly explain my uuid in models.py is -
class customer(models.Model):
customerid = models.CharField(default=str(uuid.uuid4()), max_length=500, primary_key=True)
customername=models.CharField(max_length=100)
kindly help
Updated
Form.py
class createcustomerform(ModelForm):
class Meta:
model=customer
fields=[
'customername']
Updated Models.py
import uuid
from uuid import UUID
from django.contrib.auth.models import User
from django.dispatch.dispatcher import receiver
from django.utils.translation import ugettext_lazy as _
from django.db.models.signals import pre_save
class customer(UUIDMixin,models.Model):
customername=models.CharField(max_length=100)
def __str__(self):
return self.customername
class UUIDMixin(models.Model):
uuid = models.UUIDField(blank=True,db_index=True,default=None,help_text=_('Unique identifier'),max_length=255,null=True,unique=True,verbose_name=_('UUID'))
class Meta:
abstract = True
#classmethod
def check_uuid_exists(cls, _uuid):
#Determine whether UUID exists """
manager = getattr(cls, '_default_manager')
return manager.filter(uuid=_uuid).exists()
#classmethod
def get_available_uuid(cls):
#Return an Available UUID """
row_uuid = uuid.uuid4()
while cls.check_uuid_exists(uuid=row_uuid):
row_uuid = uuid.uuid4()
return row_uuid
#receiver(pre_save)
def uuid_mixin_pre_save(sender, instance, **kwargs):
if issubclass(sender, UUIDMixin):
if not instance.uuid:
manager = getattr(instance.__class__, '_default_manager')
use_uuid = uuid.uuid4()
while manager.filter(uuid=use_uuid):
use_uuid = uuid.uuid4()
instance.uuid = use_uuid
#Automatically populate the uuid field of UUIDMixin models if not already populated.
You should use a proper UUIDField and avoid setting a default value.
Make sure the value is set when the object is created, and also ensure that the value is unique - obviously the chance of duplication in a UUID is incredibly small which is the whole point.
You could create yourself a model mixin which will add a uuid to your model(s) and ensure that the value is set when the object is saved;
class UUIDMixin(models.Model):
"""
Mixin for models contain a unique UUID, gets auto-populated on save
"""
uuid = models.UUIDField(
blank=True,
db_index=True,
# default=uuid.uuid4,
# NB: default is set to None in migration to avoid duplications
default=None,
help_text=_('Unique identifier'),
max_length=255,
null=True,
unique=True,
verbose_name=_('UUID'),
)
class Meta:
"""Metadata for the UUIDMixin class"""
abstract = True
#classmethod
def check_uuid_exists(cls, _uuid):
""" Determine whether UUID exists """
manager = getattr(cls, '_default_manager')
return manager.filter(uuid=_uuid).exists()
#classmethod
def get_available_uuid(cls):
""" Return an Available UUID """
row_uuid = uuid.uuid4()
while cls.check_uuid_exists(uuid=row_uuid):
row_uuid = uuid.uuid4()
return row_uuid
#receiver(pre_save)
def uuid_mixin_pre_save(sender, instance, **kwargs):
"""
Automatically populate the uuid field of UUIDMixin models if not already
populated.
"""
if issubclass(sender, UUIDMixin):
if not instance.uuid:
manager = getattr(instance.__class__, '_default_manager')
use_uuid = uuid.uuid4()
while manager.filter(uuid=use_uuid):
use_uuid = uuid.uuid4()
instance.uuid = use_uuid
Based on your comment, let me explain more.
The above is an abstract model, meaning it doesn't create a table itself, it can just be used by other (concrete) models so that they can use what it defines.
It's a benefit of classes & inheritance. Allowing you to not duplicate code on things that will be useful on many models.
No, in the meta you'll see abstract = True. So you define your models like MyModel(UUIDMixin, models.Model) and it gets a uuid field from this abstract model along with whatever you define.
You would use it by doing something like this;
class Customer(UUIDMixin, models.Model):
name = models.CharField(max_length=100)
If you really want to use the UUID as a primary key, maybe setup two mixins, a PrimaryUUIDMixin and the UUIDMixin, because on the whole a smaller value on the primary key may be more efficient.
You also mentioned Undefined variable: _
Typically in django you'd see an import at the top of the file like this;
from django.utils.translation import ugettext_lazy as _
This is then used to wrap strings so that they can be translated, for example, _("Hello")
Even if you don't translate your project, it's common to just include this anyway. You can read up on that here; https://docs.djangoproject.com/en/3.1/topics/i18n/translation/#standard-translation

Regular expressions based off model entry in Django?

If I create a new user in my database modeled by the following:
If this question doesn't make sense, I'm more wondering where data exists in an example url like: url(r'^members/(?P<username>\w+)/$', 'profiles.views.single')
what exactly is and how can I create a field like that?
from django.db import models
from django.contrib.auth.models import User
class Address(models.Model):
user = models.ForeignKey(User)
street_address = models.CharField(max_length = 200)
city = models.CharField(max_length = 100)
state = models.CharField(max_length = 100)
zipcode = models.IntegerField(max_length = 5)
updated = models.DateTimeField(auto_now = True, auto_now_add = False)
timestamp = models.DateTimeField(auto_now = False, auto_now_add = True)
active = models.BooleanField(default = True)
def __str__(self,):
return (self.user)
How could it be possible to have a regular expression URL mapped based on that user that lies within that model? Is it possible?
Or maybe even the phonenumber if I had a phone number field in there. Just curious, trying to better understand regex. Thanks!
I want something like
def single(request, username1):
try:
user = Address.objects.get(Address.user=username1)
single_user = user
except:
raise Http404
return render_to_response('single_user.html', locals(), context_instance=RequestContext(request))
To work with:
url(r'^members/(?P<username1>\w+)/$', 'profiles.views.single')
The only thing wrong with the example code you give is how you perform the query: you don't use the class name inside the parentheses.
user = Address.objects.get(user=username1)
If you didn't have the catch-all except clause there, you would have received a SyntaxError which might have helped you debug this yourself: that's why it's a very very bad idea to have those. Only catch the Address.DoesNotExist exception, or even better just use the get_object_or_404 shortcut.
Regular expressions has nothing to do with model from the perspective of this question. Instead Django imports and calls view based on url mapping.
View deals with models. Check the docs on How Django processes a request
url(r'^members/(?P<username>\w+)/$', 'profiles.views.single')
Here if request come to DOMAIN/members/username profiles.views.single view will be called.
Valid username format is \w . \w stands for "word character", usually [A-Za-z0-9_]
username is a field of User model which comes from django.contrib.auth.models
Check URL dispatcher and Regular expression operations as well.
update
To filter by username use
Address.objects.filter(user__username=username1) #user is a Foreignkey
For regular fields just
Address.objects.filter(field_to_filter=view_argument)

Why do I have to reference the user model this way

I was working on a Django project and I was trying to do something like this to make sure that my model worked no matter what user model is set.
from django.contrib.auth import get_user_model
class Item(models.Model):
title = models.CharField(max_length=100, )
description = models.TextField()
seller = models.ForeignKey(get_user_model())
However when I did this it resulted in errors telling me the user model couldn't be accessed so I had to change it to this
from django.conf import settings
class Item(models.Model):
title = models.CharField(max_length=100, )
description = models.TextField()
seller = models.ForeignKey(settings.AUTH_USER_MODEL)
This works fine but I thought I have done this in the past using the first method. The only difference that time being that I was using a custom user model. They both seem like they are doing the same thing to me so why do I have to use the second method? And does get_user_model() not work with the default user?
This is the source code of the get_user_model() in django:
def get_user_model():
"""
Returns the User model that is active in this project.
"""
from django.db.models import get_model
try:
app_label, model_name = settings.AUTH_USER_MODEL.split('.')
except ValueError:
raise ImproperlyConfigured("AUTH_USER_MODEL must be of the form 'app_label.model_name'")
user_model = get_model(app_label, model_name)
if user_model is None:
raise ImproperlyConfigured("AUTH_USER_MODEL refers to model '%s' that has not been installed" % settings.AUTH_USER_MODEL)
return user_model
As you can see, it pulls the AUTH_USER_MODEL variable from your settings as you do but extracting the app_label and the user class itself. If it does not work you should see one of the two errors in the terminal when this call is done.
I think your answer lies in the Django source. It depends on your setup what happens. Older versions might do it a bit differently.

How can you create a non-empty CharField in Django?

I have a simple model which looks like this:
class Group(models.Model):
name = models.CharField(max_length = 100, blank=False)
I would expect this to throw an integrity error, but it does not:
group = Group() # name is an empty string here
group.save()
How can I make sure that the name variable is set to something non-empty? I.e to make the database reject any attempts to save an empty string?
another option that doesn't require you to manually call clean is to use this:
name = models.CharField(max_length=100, blank=False, default=None)
blank will prevent an empty string to be provided in the admin or using a form or serializer (most cases). However as pointed out in the comments, this unfortunately does not prevent things like model.name = "" (manually setting blank string)
default=None will set name to None when using something like group = Group(), thus raising an exception when calling save
From the Django docs in this case, your name will be stored as an empty string, because the null field option is False by default. if you want to define a custom default value, use the default field option.
name = models.CharField(max_length=100, blank=False, default='somevalue')
On this page, you can see that the blank is not database-related.
Update:
You should override the clean function of your model, to have custom validation, so your model def will be:
class Group(models.Model):
name = models.CharField(max_length=100, blank=False)
def clean(self):
from django.core.exceptions import ValidationError
if self.name == '':
raise ValidationError('Empty error message')
Or you can replace ValidationError to something else. Then before you call group.save() call group.full_clean() which will call clean()
Other validation related things are here.
Or you can simply use MinLengthValidator with a 1-char minimum:
from django.core.validators import MinLengthValidator
class Company(BaseModel):
"""Company"""
name = models.CharField(max_length=255,
validators=[MinLengthValidator(1)])
I spent a long time looking for the best solution for this simple (and old) problem, And as of Django 2.2, there is actually a really simple answer, so I'll write it here in case someone still encounters the same problem:
Since Django 2.2, we can define CheckConstraints, so it's easy to define a non-empty string constraint:
from django.db import models
class Article(models.Model):
title = models.CharField(max_length=32)
class Meta:
constraints = [
models.CheckConstraint(check=~models.Q(title=""), name="non_empty_title")
]
Django’s validation system assumes that all fields are required,unless you mention that its ok to leave it blank..
Have you registered the class in Admin ? does it show errors when you leave it blank ??

Django: "ZeroToOneField" DoesNotExist Error

I'm trying to determine the best way to make a "zero-to-one" relationship between two models. For example, a model named Post can have zero or one related model instances of a Model called PostExtra. I'd like the reverse to be true as well.
from django.db import models
class PostExtra(models.Model):
author = models.CharField(max_length=64)
active = models.BooleanField(default=False)
"""
Assigned a property to prevent DoesNotExist error when calling
self.post, but property does not override self.post properly
for some reason.
"""
def _get_post(self):
return_value=None
try:
return_value = self.post
except:
pass
return return_value
def _set_post(self, post):
self.post = post
post = property(_get_post, _set_post)
def __unicode__(self):
return "%s" % (self.author)
class Post(models.Model):
title = models.CharField(max_length=64)
text = models.TextField()
extra = models.OneToOneField('a.PostExtra', blank=True, null=True)
def __unicode__(self):
return "%s" % (self.title)
Here, I can create a Post()
>>> p = Post(title="test 1", text="test text")
>>> p.save()
>>> p.extra # this returns None as it should
As above, since I made Post.extra a OneToOneField with blank=True/null=True, p.extra will return Null if no PostExtra is assigned. However, if I do the reverse and try to access PostExtra.post, I get a DoesNotExist error.
>>> pe = PostExtra(author='John Doe')
>>> pe.save()
>>> pe.post
...
DoesNotExist: Post matching query does not exist.
I tried assigning a property on PostExtra to override the PostExtra.post using a property, but I still get the error. Has anyone found a way to get OneToOneFields to not throw an exception (and return Null) when trying to access a non-existent related element?
Any advice is much appreciated.
You would need to specify a different related_name on your relationship in order to make this type of code work.
from django.core.exceptions import ObjectDoesNotExist
class PostExtra(models.Model):
pass ## Brevity.
def _get_post(self):
return_value=None
try:
return_value = self._post
except ObjectDoesNotExist: ## Be explicit if you can.
pass
return return_value
def _set_post(self, post):
self._post = post
post = property(_get_post, _set_post)
class Post(models.Model):
pass ## Brevity.
extra = models.OneToOneField('a.PostExtra', blank=True,
null=True, related_name='_post')
You can then access the post in a few different ways:
>>> pe = PostExtra(author='John Doe')
>>> pe.save()
>>> pe.post
None
>>> pe._post
DoesNotExist: Post matching query does not exist.
Ninja Edit:
The question may be raised, "Why do I have to do it this way?". The answer is because when the Django model classes set up your PostExtra object, it is creating PostExtra.post as a reference back to Post. I'm not familiar with the code itself, but I doubt it checks to make sure the coast is clear before doing the assignment, since the programmer told it to make that relation. As a result, you have to specify a non-conflicting property for Django's model classes to use, thus the related_name argument.