Regular expressions based off model entry in Django? - regex

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)

Related

How to get my Django template to recognize a model method?

In my django template <p>This user is unsubscribed {{sub.is_unsubscribed}}</p> always displays "This user is unsubcribed False" even when it should show True based on the following models.py
from django.shortcuts import get_object_or_404
class Subscriber(models.Model):
email = models.CharField(max_length=12)
first_name = models.CharField(max_length=50)
last_name = models.CharField(max_length=50)
create_date = models.DateTimeField(auto_now_add=True)
def is_unsubscribed(self):
try:
get_object_or_404(MasterUnsubscriber, unsubcriber_email=self.email)
return True
except:
return False
def __str__(self):
return self.email
class MasterUnsubscriber(models.Model):
unsubscriber_email= models.CharField(max_length=12)
And for structural reasons of my app, I do not want to move the unsubscribe to the Subscriber model as a boolean. How can this be resolved while keeping same model formats.
get_object_or_404 will raise an error if there is no element at all, or when there are multiple such elements, since the underlying implementation is to use .get(..). You can make use of .exists() instead:
class Subscriber(models.Model):
# …
def is_unsubscribed(self):
return MasterUnsubscriber.objects.filter(unsubscriber_email=self.mail).exists()
That being said, I would advice to make use a ForeignKey [Django-doc] to the subscriber, not by matching the email address. This will be inefficient, since search on a non-indexed column is slow, and furthermore if the user later changes their email, then the all of a sudden, these can be subscribed again. Django also has convenient ways to filter or make aggregates on related objects, so you get more out of the Django ORM.

Django Listview for model related to user returning "No user" error

I'm trying to produce a list of user addresses so that a user can review and then update, delete etc...
Currently I'm using ListView with:
class AddressListView(LoginRequiredMixin, ListView):
model = Address
def get_object(self):
return self.model.objects.get(user=self.request.user.pk)
with the Address model:
class Address(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL)
house_name = models.CharField(max_length=255, null=True)
house_number = models.CharField(max_length=255, null=True)
street_name = models.CharField(max_length=255, null=True)
.......
And the url pattern:
....
url(
regex=r'^address/$',
view=views.AddressListView.as_view(),
name='address_list'
),
...
However when I try to request that view I get an error "Page not found (404), No user found matching the query"
The error is:
Since you are writing a list view, you should override get_queryset (which returns a queryset of objects) instead of get_object (which returns a single object).
class AddressListView(LoginRequiredMixin, ListView):
model = Address
def get_queryset(self):
return self.model.objects.filter(user=self.request.user)
Secondly, you are getting the 404 because the wrong view is handling the request. Django uses the first URL pattern that matches, and in this case address/ is matched by the regex r'^(?P<username>[\w.#+-]+)/$, so Django tries to find a user with username='address'.
You can fix this issue by moving the address_list URL pattern above the detail URL pattern - although this would prevent you viewing the detail page if you have a user with 'address' as the username in future. Another option is to change one or both of the regexes so that they don't clash, e.g. r'^(?P<username>[\w.#+-]+)/detail/'.
Remove the .pk from your query, as that is done automatically by Django for you.
return self.model.objects.get(user=self.request.user)
Alternatively add an _id to the user:
return self.model.objects.get(user_id=self.request.user.pk)

Django: Checking CharField format in form with a regular expression

class CapaForm(forms.Form):
capa = forms.CharField(required=False)
Upon form submission I want to check the format of the capa field. I want to require the user to enter the capa format correctly as 6 numbers, a dash, and two numbers. (######-##)
def search(self):
capa = self.cleaned_data.get('capa', None)
if ("\d{6}\-\d{2}" or None) not in capa:
raise forms.ValidationError("CAPA format needs to be ######-##!")
It's currently not letting me submit a correctly formatted capa and throws the ValidationError. I think the problem is I'm trying to compare a regular expression to an object. How can I check the format of the 'capa' the user tries to submit?
*********UPDATE
Everything is working now EXCEPT when I type the wrong format in the CAPA field. I get the error The view incidents.views.index didn't return an HttpResponse object. It returned None instead. Is this related to the changes I made?
from django.core.validators import RegexValidator
my_validator = RegexValidator("\d{6}\-\d{2}", "CAPA format needs to be ######-##.")
class CapaForm(forms.Form):
capa = forms.CharField(
label="CAPA",
required=False, # Note: validators are not run against empty fields
validators=[my_validator]
)
def search(self):
capa = self.cleaned_data.get('capa', None)
query = Incident.objects.all()
if capa is not '':
query = query.filter(capa=capa)
return(query)
First you need a regex validator:
Django validators / regex validator
Then, add it into the validator list of your field:
using validators in forms
Simple example below:
from django.core.validators import RegexValidator
my_validator = RegexValidator(r"A", "Your string should contain letter A in it.")
class MyForm(forms.Form):
subject = forms.CharField(
label="Test field",
required=True, # Note: validators are not run against empty fields
validators=[my_validator]
)
you could also ask from both part in your form, it would be cleaner for the user :
class CapaForm(forms.Form):
capa1 = forms.IntegerField(max_value=9999, required=False)
capa2 = forms.IntegerField(max_value=99, required=False)
and then just join them in your view :
capa = self.cleaned_data.get('capa1', None) + '-' + self.cleaned_data.get('capa2', None)
You can also use RegexField. It's the same as CharField but with additional argument regex. Under the hood it uses validators.
Example:
class MyForm(forms.Form):
field1 = forms.RegexField(regex=re.compile(r'\d{6}\-\d{2}'))
Regex validator does not work for me in Django 2.2
Step to set up custom validation for a field value:
define the validation function:
def number_code_validator(value):
if not re.compile(r'^\d{10}$').match(value):
raise ValidationError('Enter Number Correctly')
In the form add the defined function to validators array of the field:
number= forms.CharField(label="Number",
widget=TextInput(attrs={'type': 'number'}),
validators=[number_code_validator])

Django Field Regex Validation

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],
)

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 ??