Second Chapter
from __future__ import unicode_literals
from django.core.validators import RegexValidator
from django.db import models
# Create your models here.
class College(models.Model):
name = models.CharField(max_length=200)
address = models.TextField()
phone_regex = RegexValidator(regex=r'^[789]\d{9}$', message="Invalid phone number.")
contact_no = models.CharField(validators=[phone_regex],max_length=200, blank=True)
def __str__(self):
return self.name
Contact number validation with regex in model.
Extract post data
data = request.POST
name = request.POST.get('name', '')
venue = request.POST.get('venue', '')
print name, venue
Lambda Functions
filter
# Program to filter out
# only the even items from
# a list using filter() and
# lambda functions
my_list = [1, 5, 4, 6, 8, 11, 3, 12]
new_list = list(filter(lambda x: (x%2 == 0) , my_list))
print(new_list)
Output:
[4, 6, 8, 12]
map
# Program to double each
# item in a list using map() and
# lambda functions
my_list = [1, 5, 4, 6, 8, 11, 3, 12]
new_list = list(map(lambda x: x * 2 , my_list))
print(new_list)
Output:
[2, 10, 8, 12, 16, 22, 6, 24]
Get Fields names from Model
from django.contrib.auth.models import User
print list(map(lambda x: (x.name) , User()._meta.fields))
Output:
[u'id', 'password', 'last_login', 'is_superuser', 'username', 'first_name', 'last_name', 'email', 'is_staff', 'is_active', 'date_joined']
List to Set Conversion
lst1 = list({'Username':'Pratik','Password':'pratik123'})
lst2 = list({'Username':'Pratik','Password':'pratik123','Email':'[email protected]'})
set1, set2 = set(lst1), set(lst2)
diff = set2.difference(set1)
diff = list(diff)
Output:
['Email']
# Note: Converting to Dict to list gives list of keys
In [98]: lst1
Out[98]: ['Username', 'Password']
# Note: Convert dict to set of keys
In [101]: print set({'Username':'Pratik','Password':'pratik123','Email':'[email protected]'})
set(['Username', 'Password', 'Email'])
Jsonp handling at server
response = {'status':True, 'message': 'Not a jsonp request'}
if request.GET['callback'] != None:
response = request.GET['callback'] + '(' + json.dumps(response) + ');'
return HttpResponse(response, 'text/javascript; charset=utf-8')
else:
return HttpResponse(json.dumps(response), content_type="application/json")
# url
# localhost:8000/api/jsonp/?callback=myFunction
<script>
var apiservices = {};
apiservices.api = 'http://localhost:8000/';
var data = {'name':'abc'};
apiservices.response = function(response){
console.log(response);
alert(JSON.stringify(response));
}
var getData = function(data,callback){
console.log(apiservices.api + 'api/jsonp/?callback=' + callback);
var requestEnvelope = {
url: apiservices.api + 'api/jsonp/?callback=' + callback,
type: 'POST',
contentType: 'application/json',
jsonp: "callback",
data: JSON.stringify(data),
complete: function(data){
apiservices.response(data.responseText);
}
}
$.ajax(requestEnvelope);
}
$('.btn').on('click',function(){
getData(data,'apiservices.response');
});
</script>
String to Dict And Vice-Versa
dict1 = {'one':1, 'two':2, 'three': {'three.1': 3.1, 'three.2': 3.2 }}
str1 = str(dict1)
dict2 = eval(str1)
print dict1==dict2
Creating database objects
from blog.models import Blog
b = Blog(name='Beatles Blog', tagline='All the latest Beatles news.')
b.save()
Sanitize Strings in a Dict
In [27]: s = {'address': u'sdasdf dfad sdf ', 'age': 25, 'city': ' bsl ', 'name': ' Pratik '}
In [28]: x = map(lambda x: (x.strip() if type(x) == str or type(x) == unicode else x), s.values())
In [29]: dict(zip(s.keys(), x))
Out[30]: {'address': u'sdasdf dfad sdf', 'age': 25, 'city': 'bsl', 'name': 'Pratik'}
Each view gets request data in a dict. The first task of the view is to sanitize the data viz. trim all white spaces from all the strings, make file names database safe (i.e. remove all special characters, slashes, dashes etc), lowercase all emails etc. above snippet address the issue of trimming all the strings in request dict
Regex
def helper_sanitize(data, t = 'dict'):
#dict
if(t == 'dict'):
x = map(lambda x: (x.strip() if type(x) == str or type(x) == unicode else x), data.values())
return dict(zip(data.keys(), x))
if(t == 'filename'):
return re.sub('[^0-9a-zA-Z._]+', '', data)
if(t == 'email'):
return data.lower()
def helper_validate(data, t = 'email'):
#email
if t == 'email' and not re.match(r"[^@]+@[^@]+\.[^@]+", data):
return False
elif t == 'mobileno' and not re.match(r"^[789]\d{9}$", data):
return False
elif t == 'landlineno' and not re.match(r"^[1-9][0-9]{6}$", data):
return False
elif t == 'pincode' and not re.match(r"^[1-9][0-9]{5}$", data):
return False
else:
return True
Download csv
import csv
from django.http import HttpResponse
def some_view(request):
# Create the HttpResponse object with the appropriate CSV header.
response = HttpResponse(content_type='text/csv')
response['Content-Disposition'] = 'attachment; filename="somefilename.csv"'
writer = csv.writer(response)
writer.writerow(['First row', 'Foo', 'Bar', 'Baz'])
writer.writerow(['Second row', 'A', 'B', 'C', '"Testing"', "Here's a quote"])
return response
Get model fields key and values
a = User.objects.get(id=1)
print [(field.name, getattr(a,field.name)) for field in a._meta.fields]
One/single line for loop example
Compare Ref keys with actual received keys
data = json.loads(request.body)
refkeys = {'password', 'username', 'first_name', 'last_name', 'email'}
reqkeys = set(data)
print "-----------------"
print reqkeys
print "================="
print refkeys
print "*****************"
if len(refkeys.difference(reqkeys)) > 0:
return HttpResponse(json.dumps({'status':False,
'message': 'Keys changed',
'diff': list(refkeys.difference(reqkeys)),
'expected': list(refkeys),
'received': list(reqkeys)}), content_type="application/json")
Save Password
from django.contrib.auth.models import User
u = User.objects.get(username='smith')
u.set_password('new password')
u.save()
Authenticate User at login
from django.contrib.auth import authenticate
user = authenticate(username='smith', password='secret')
if user is not None:
# the password verified for the user
if user.is_active:
print("User is valid, active and authenticated")
else:
print("The password is valid, but the account has been disabled!")
else:
# the authentication system was unable to verify the username and password
print("The username and password were incorrect.")
user name and password is available only at login in all other subsequent requests use the is_authenticated() method user authentication, permissions, login
Authenticate user is subsequent request
if request.user.is_authenticated():
# Do something for authenticated users.
else:
# Do something for anonymous users.
How to log a user in
from django.contrib.auth import authenticate, login
def my_view(request):
username = request.POST['username']
password = request.POST['password']
user = authenticate(username=username, password=password)
if user is not None:
if user.is_active:
login(request, user)
# Redirect to a success page.
else:
# Return a 'disabled account' error message
else:
# Return an 'invalid login' error message.
How to log user out
def logout_view(request):
logout(request)
# Redirect to a success page.
login_required decorator
from django.contrib.auth.decorators import login_required
@login_required(login_url='/accounts/login/')
def my_view(request):
Note that if you don’t specify the login_url parameter, you’ll need to ensure that the settings.LOGIN_URL and your login view are properly associated. login required decorator
from django.contrib.auth import views as auth_views url(r'^accounts/login/$', auth_views.login),
Djagno ORM
Q object queries -- search queries -- checking multiple conditions to filter
views.py
file in an app
from django.db.models import Q
from .models import Product
# some view function
...
filtered_products = Product.objects.filter(
Q(name__startswith='Ad', profile_image__isnull=True) |
Q(added__year_lt=2015, added__year_gte=2013)
)
ORM QuerySet
Ref: QuerySet
DB queries Django relationships
DB query mechanism and optimisation
### Ordering Objects ###
# Asc
In [99]: Post.objects.order_by('id')
Out[99]: [<Post: My First Blog Post>, <Post: Sample Blog 2>, <Post: Sample Blog 3>, <Post: Sample blog 4>, <Post: Sample blog 5>, <Post: Sample blog 6>, <Post: Sample title>]
# Desc
In [100]: Post.objects.order_by('-id')
Out[100]: [<Post: Sample title>, <Post: Sample blog 6>, <Post: Sample blog 5>, <Post: Sample blog 4>, <Post: Sample Blog 3>, <Post: Sample Blog 2>, <Post: My First Blog Post>]
#All Objects
Post.objects.all()
[<Post: my post title>, <Post: another post title>]
#Get single object
In [103]: User.objects.get(username='pratik')
Out[103]: <User: pratik>
#Create Object
In [13]: from django.contrib.auth.models import User
In [14]: me = User.objects.get(username='pratik')
...: Post.objects.create(author=me, title='Sample title', text='Test')
Out[14]: <Post: Sample title>
### Filter Objects ###
In [9]: Post.objects.filter(title='Sample blog 5')
Out[9]: [<Post: Sample blog 5>]
# Exact match
In [21]: Post.objects.filter(title__exact='Sample blog 5')
Out[21]: [<Post: Sample blog 5>]
# Contains
In [20]: Post.objects.filter(title__contains='first')
Out[20]: [<Post: My First Blog Post>]
# In a given list.
In [34]: Post.objects.filter(id__in=[1,5,3])
Out[34]: [<Post: My First Blog Post>, <Post: Sample Blog 2>, <Post: Sample blog 4>]
# Less than.
In [37]: Post.objects.filter(id__lt=4)
Out[37]: [<Post: My First Blog Post>, <Post: Sample Blog 2>]
# Greater than
In [42]: Post.objects.filter(id__gt=3)
Out[42]: [<Post: Sample Blog 3>, <Post: Sample blog 4>, <Post: Sample blog 5>, <Post: Sample blog 6>, <Post: Sample title>]
# Greater than or equal to.
In [43]: Post.objects.filter(id__gte=3)
Out[43]: [<Post: Sample Blog 2>, <Post: Sample Blog 3>, <Post: Sample blog 4>, <Post: Sample blog 5>, <Post: Sample blog 6>, <Post: Sample title>]
# Case-sensitive starts-with.
In [47]: Post.objects.filter(title__startswith='s')
Out[47]: [<Post: Sample Blog 2>, <Post: Sample Blog 3>, <Post: Sample blog 4>, <Post: Sample blog 5>, <Post: Sample blog 6>, <Post: Sample title>]
# Ends with
In [53]: Post.objects.filter(title__endswith='post')
Out[53]: [<Post: My First Blog Post>]
# Range
In [61]: Post.objects.filter(created_date__range=(start_date, end_date))
Out[61]: [<Post: Sample blog 6>]
In [63]: Post.objects.filter(id__range=(2, 5))
Out[63]: [<Post: Sample Blog 2>, <Post: Sample Blog 3>, <Post: Sample blog 4>]
# For datetime fields
# pip install pytz : required to work field lookup date
In [10]: Post.objects.filter(created_date__date=datetime.date(2016, 7, 13))
Out[10]: [<Post: Sample blog 6>]
In [15]: Post.objects.filter(created_date__date__gte=datetime.date(2016, 7, 13))
Out[15]: [<Post: Sample blog 6>, <Post: Sample title>]
In [16]: Post.objects.filter(created_date__year=2016)
Out[16]: [<Post: My First Blog Post>, <Post: Sample blog 5>, <Post: Sample blog 6>, <Post: Sample title>]
In [17]: Post.objects.filter(created_date__month=7)
Out[17]: [<Post: My First Blog Post>, <Post: Sample blog 5>, <Post: Sample blog 6>, <Post: Sample title>]
In [18]: Post.objects.filter(created_date__day=13)
Out[18]: [<Post: Sample blog 6>]
In [17]: Post.objects.filter(created_date__hour=5)
Out[17]: [<Post: Sample blog 6>]
In [18]: Post.objects.filter(created_date__minute=5)
Out[18]: []
In [19]: Post.objects.filter(created_date__second=5)
Out[19]: []
In [22]: Post.objects.filter(created_date__isnull=False)
Out[22]: [<Post: My First Blog Post>, <Post: Sample Blog 2>, <Post: Sample Blog 3>, <Post: Sample blog 4>]
#Regular Expression
In [52]: Post.objects.filter(title__regex=r'^My')
Out[52]: [<Post: My First Blog Post>]
# prefetch()for multiple choices
Question.objects.prefetch_related(Prefetch('choice_set')).get().choice_set.all()
[<Choice: Not much>, <Choice: The sky>, <Choice: Just hacking again>]
# This will only execute two queries regardless of the number of Question
# and Choice objects.
>>> Question.objects.prefetch_related(Prefetch('choice_set')).all()
[<Question: Question object>]
distinct values
In [30]: Scan_Log.objects.filter(
...: server_timestamp__year = 2016,
...: server_timestamp__month = 8,
...: server_timestamp__day = 29).values('identified_user').distinct()
4. HTML template load staticfiles, for loop, if else, verbatim
Reference:
<!-- base.html -->
<html>
<head>
{% load staticfiles %}
<link rel="stylesheet" href="{% static 'css/style.css' %}">
</head>
<body>
Welcome
{% block content %}
{% endblock %}
<footer></footer>
</body>
</html>
<!-- child_page.html -->
{% extends 'layout.html' %}
{% block content %}
<h1>
Child html
</h1>
{% endblock %}
If Statement
<div class="page-header">
{% if user.is_authenticated %}
<a href="{% url 'post_new' %}" class="top-menu"><span class="glyphicon glyphicon-plus"></span></a>
{% endif %}
<h1><a href="/">Django Girls Blog</a></h1>
</div>
If else statements
{% if athlete_list %}
Number of athletes: {{ athlete_list|length }}
{% elif athlete_in_locker_room_list %}
Athletes should be out of the locker room soon!
{% else %}
No athletes.
{% endif %}
For loop on list
<ul>
{% for athlete in athlete_list %}
<li>{{ athlete.name }}</li>
{% endfor %}
</ul>
For loop on dict
{% for key, value in data.items %}
{{ key }}: {{ value }}
{% endfor %}
Commonly used regex for URL patterns
^ for beginning of the text
$ for end of text
\d for a digit
+ to indicate that the previous item should be repeated at least once
() to capture part of the pattern
Solution for: CSRF verification failed. Request aborted
from django.views.decorators.csrf import csrf_exempt
from django.http import HttpResponse
@csrf_exempt
def my_view(request):
return HttpResponse('Hello world')
Datetime
import datetime
# Epoch to datetime
In [16]: datetime.datetime.fromtimestamp(1468830730)
Out[16]: datetime.datetime(2016, 7, 18, 14, 2, 10)
# Formatting datetime
# 12 hour clock
In [2]: datetime.datetime.fromtimestamp(1468830730).strftime('%d/%m/%Y %I:%M:%S %p')
Out[2]: '18/07/2016 02:02:10 PM'
# 24 hour clock
In [3]: datetime.datetime.fromtimestamp(1468830730).strftime('%d/%m/%Y %H:%M:%S')
Out[3]: '18/07/2016 14:02:10'
# datetime to Epoch
In [17]: datetime.datetime(2016, 7, 18, 14, 2, 10).strftime('%s')
Out[17]: '1468830730'
# current datetime to Epoch
In [22]: datetime.datetime.now().strftime('%s')
Out[22]: '1468835844'
# Get current date
In [19]: datetime.datetime.now()
Out[19]: datetime.datetime(2016, 7, 18, 14, 23, 20, 776251)
# Get current time only
In [20]: datetime.datetime.time(datetime.datetime.now())
Out[20]: datetime.time(14, 23, 34, 463388)
Export to pdf
Installation
export LC_ALL=en_US.UTF-8
export LANG=en_US.UTF-8
sudo apt-get install python-dev python-pip python-lxml libcairo2 libpango1.0-0 libgdk-pixbuf2.0-0 libffi-dev shared-mime-info
# activate virtualenv
pip install Weasyprint
If you get this error when installing Weasyprint,
Command "/home/pratik/Environments/envpdfdemo/bin/python2 -u -c "import setuptools, tokenize;file='/tmp/pip-build-R8PDDf/lxml/setup.py';exec(compile(getattr(tokenize, 'open', open)(file).read().replace('\r\n', '\n'), __file, 'exec'))" install --record /tmp/pip-CUVPUe-record/install-record.txt --single-version-externally-managed --compile --install-headers /home/pratik/Environments/env_pdf_demo/include/site/python2.7/lxml" failed with error code 1 in /tmp/pip-build-R8PDDf/lxml/
Solution:
apt-get install libxml2-dev
apt-get install libxslt1-dev
pip install lxml
Then install Weasyprint again
Usage:
report.html
<html>
<head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8" />
</head>
<body>
<h1>Hello {{ you.first_name }} {{ you.last_name }} !</h1>
<div style="width:100%; height:50mm; background:#FF0000;">
hello
</div>
</body>
</html>
views.py
from django.contrib.auth.decorators import login_required
from django.template.loader import get_template
from django.template import RequestContext
from django.http import HttpResponse
from django.conf import settings
from weasyprint import HTML, CSS
@login_required(login_url='/admin/login/')
def get_report(request):
html_template = get_template('report.html')
user = request.user
rendered_html = html_template.render(RequestContext(request, {'you': user})).encode(encoding="UTF-8")
pdf_file = HTML(string=rendered_html).write_pdf()
# to change page size and margins
# pdf_file = HTML(string=rendered_html).write_pdf(stylesheets=[CSS(string='@page { size: A4; margin: 1cm }')])
http_response = HttpResponse(pdf_file, content_type='application/pdf')
http_response['Content-Disposition'] = 'filename="report.pdf"'
return http_response
urls.py
from django.conf.urls import url
from django.contrib import admin
from .views import get_report
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^pdf/', get_report),
]
controlling pdf page attributes (page size, margins, page breaks, page orientation
controlling pdf page attributes (page size, margins, page breaks, page orientation
Search available Django Packages
Model Reverse Lookup Query
models.py
from django.db import models
class Blog(models.Model):
name = models.CharField(max_length=100)
tagline = models.TextField()
class Entry(models.Model):
blog = models.ForeignKey(Blog)
headline = models.CharField(max_length=255)
views.py
b = Blog.objects.get(id=1)
b.entry_set.all() # Returns all Entry objects related to Blog.
Model Reverse Lookup Query with related name
models.py
from django.db import models
class Blog(models.Model):
name = models.CharField(max_length=100)
tagline = models.TextField()
class Entry(models.Model):
blog = models.ForeignKey(Blog, related_name='entry')
headline = models.CharField(max_length=255)
views.py
b = Blog.objects.get(id=1)
b.entry.all() # Returns all Entry objects related to Blog.
Serialize object
from Event.models import Event
import datetime
import json
from django.core import serializers
def latest_events(request):
currentdate = datetime.datetime.now().strftime('%s')
events = Event.objects.filter(datetime__gte=currentdate)
data = serializers.serialize('json', events)
return HttpResponse(data, content_type="application/json")
Convert unicode string dictionary into dictionary
from django.core import serializers
import ast
In [135]: cart_items = CartItem.objects.filter(cart__customer__user__id=1)
...: data = serializers.serialize('json', cart_items)
In [136]: data[0]
Out[136]: u'['
In [137]: data
Out[137]: u'[{"model": "customer.cartitem", "pk": 57, "fields": {"cart": 11, "product": 1, "quantity": 3}}, {"model": "customer.cartitem", "pk": 58, "fields": {"cart": 11, "product": 2, "quantity": 2}}]'
In [138]: type(data)
Out[138]: unicode
In [139]: new_data = ast.literal_eval(data)
In [140]: type(new_data)
Out[140]: list
In [141]: new_data[0]
Out[141]: {'fields': {'cart': 11, 'product': 1, 'quantity': 3},
'model': 'customer.cartitem',
'pk': 57}
In [142]: new_data
Out[142]: [{'fields': {'cart': 11, 'product': 1, 'quantity': 3},
'model': 'customer.cartitem',
'pk': 57},
{'fields': {'cart': 11, 'product': 2, 'quantity': 2},
'model': 'customer.cartitem',
'pk': 58}]
Extracting data from request headers
# BAD!
def ua_display_bad(request):
ua = request.META['HTTP_USER_AGENT'] # Might raise KeyError!
return HttpResponse("Your browser is %s" % ua)
# GOOD (VERSION 1)
def ua_display_good1(request):
try:
ua = request.META['HTTP_USER_AGENT']
except KeyError:
ua = 'unknown'
return HttpResponse("Your browser is %s" % ua)
# GOOD (VERSION 2)
def ua_display_good2(request):
ua = request.META.get('HTTP_USER_AGENT', 'unknown')
return HttpResponse("Your browser is %s" % ua)
Give User friendly name to choicefield
class Tag(models.Model):
#name = choice
TRENDING = 'TR'
FEATURED = 'FE'
NORMAL = 'NR'
TAG_CHOICES = (
(TRENDING, 'Trending'),
(FEATURED, 'Featured'),
(NORMAL, 'Normal'),
)
TagName = models.CharField(
max_length=2,
choices=TAG_CHOICES,
default=NORMAL,
)
def __str__(self):
return self.get_TagName_display()
For email sending
settings.py
EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'
Iterate 2 steps over a list
mylist = [1,2,3,4,5,6,7,8,9,10]
for i in mylist[::2]:
print i,
# prints 1 3 5 7 9
for i in mylist[1::2]:
print i,
# prints 2 4 6 8 10
Get all models for app
from django.apps import apps
app_models = apps.get_app_config('my_app').get_models()
for model in app_models:
print model
unique_together with many to many fields
from django.db import models
from django.db.models.signals import m2m_changed
from django.dispatch import receiver
from django.db.utils import IntegrityError
class Publisher(models.Model):
name = models.CharField(max_length=30)
class Book(models.Model):
"""
A Book may have multiple publishers.
But a two books cannot have same name and a common publisher.
"""
name = models.CharField(max_length=30)
publishers = models.ManyToManyField(Publisher)
@receiver(m2m_changed, sender=Book.publishers.through)
def verify_uniqueness(sender, **kwargs):
book = kwargs.get('instance', None)
action = kwargs.get('action', None)
publishers = kwargs.get('pk_set', None)
if action == 'pre_add':
for publisher in publishers:
if Book.objects.filter(name=book.name).filter(publishers=publisher):
raise IntegrityError('Book with name %s already exists for publisher %s' % (book.name, Publisher.objects.get(pk=publisher)))
https://djangosnippets.org/snippets/2552/
Generate Class diagram from models
You can use django-extensions
app for generating model visualisations.
pip install django-extensions
setting.py
INSTALLED_APPS = (
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.sites',
'django.contrib.messages',
'django.contrib.staticfiles',
'...',
'django_extensions',
'django.contrib.admin',
# Uncomment the next line to enable admin documentation:
# 'django.contrib.admindocs',
)
Give this command in terminal
python manage.py graph_models -a -o myapp_models.png
This will generate a png file named myapp_models.png. It will have visualised image of the models.
Reference link: http://stackoverflow.com/a/16505813
ManyToMany Relationship with Additional Fields
from django.db import models
class Person(models.Model):
name = models.CharField(max_length=128)
def __str__(self): # __unicode__ on Python 2
return self.name
class Group(models.Model):
name = models.CharField(max_length=128)
members = models.ManyToManyField(Person, through='Membership')
def __str__(self): # __unicode__ on Python 2
return self.name
class Membership(models.Model):
person = models.ForeignKey(Person)
group = models.ForeignKey(Group)
date_joined = models.DateField()
invite_reason = models.CharField(max_length=64)
Reference Link: http://stackoverflow.com/a/4443212
Django admin.py generator
https://pypi.python.org/pypi/django-admin-generator/2.0.0
https://django-admin-generator.readthedocs.io/en/latest/
Display which sql query is executed when filtering
In [19]: import logging
In [20]: l = logging.getLogger('django.db.backends')
In [21]: l.setLevel(logging.DEBUG)
In [22]: l.addHandler(logging.StreamHandler())
In [23]: User.objects.all().order_by('-id')[:10]
(0.000) SELECT "auth_user"."id", "auth_user"."username", "auth_user"."first_name", "auth_user"."last_name", "auth_user"."email", "auth_user"."password", "auth_user"."is_staff", "auth_user"."is_active", "auth_user"."is_superuser", "auth_user"."last_login", "auth_user"."date_joined" FROM "auth_user" ORDER BY "auth_user"."id" DESC LIMIT 10; args=()
Out[23]: [<User: hamdi>]