<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Alejandro Riera</title>
    <description>The latest articles on DEV Community by Alejandro Riera (@ariera).</description>
    <link>https://dev.to/ariera</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F33761%2Fe0c90d79-ae30-4dd9-af88-6802594c15eb.jpeg</url>
      <title>DEV Community: Alejandro Riera</title>
      <link>https://dev.to/ariera</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/ariera"/>
    <language>en</language>
    <item>
      <title>TIL: How to debug cron jobs</title>
      <dc:creator>Alejandro Riera</dc:creator>
      <pubDate>Tue, 27 Feb 2018 11:05:28 +0000</pubDate>
      <link>https://dev.to/ariera/til-how-to-debug-cron-jobs-5h26</link>
      <guid>https://dev.to/ariera/til-how-to-debug-cron-jobs-5h26</guid>
      <description>&lt;p&gt;Today I learned how to properly debug cron jobs, thanks to &lt;a href="https://serverfault.com/a/85906"&gt;https://serverfault.com/a/85906&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;They key is to recreate the correct environment in which your scripts get executed. I’m going to do this for &lt;code&gt;root&lt;/code&gt; but you can do this with every user.&lt;/p&gt;

&lt;p&gt;First: edit your crontab and add one line&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;crontab -e
* * * * * /usr/bin/env &amp;gt; /root/cron-env
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once it has had the chance to execute once you can remove it.&lt;/p&gt;

&lt;p&gt;Second: let’s create a new script called &lt;code&gt;run-as-cron&lt;/code&gt; that will run your scripts with the correct environment cron is running.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cd /root
touch run-as-cron
chmod +x run-as-cron
vim run-as-cron
#!/bin/bash
/usr/bin/env -i $(cat /root/cron-env) "$@"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Finally, debug your problematic script like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/root/run-as-cron /the/problematic/script --with arguments --and parameters
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>todayilearned</category>
    </item>
    <item>
      <title>Django + webpack + Vue.js: setting up a new project that’s easy to develop and deploy (part 1)</title>
      <dc:creator>Alejandro Riera</dc:creator>
      <pubDate>Tue, 26 Sep 2017 06:55:25 +0000</pubDate>
      <link>https://dev.to/ariera/django--webpack--vuejs-setting-up-a-new-project-thats-easy-to-develop-and-deploy-part-1-4o2</link>
      <guid>https://dev.to/ariera/django--webpack--vuejs-setting-up-a-new-project-thats-easy-to-develop-and-deploy-part-1-4o2</guid>
      <description>&lt;h1&gt;
  
  
  &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fr9fou2ac64ymfjyt76pf.png" alt="django webpack vue logos" width="800" height="156"&gt;
&lt;/h1&gt;

&lt;p&gt;&lt;strong&gt;UPDATE: I recently created a working project at &lt;a href="https://github.com/ariera/django-vue-template" rel="noopener noreferrer"&gt;ariera/django-vue-template&lt;/a&gt; using the latest version of the vue-webpack template and bundling all the changes highlighted in this post in just this commit &lt;a href="https://github.com/ariera/django-vue-template/commit/8a5c552a20bb9ec7e5751adef3b5d2e26addbcf4" rel="noopener noreferrer"&gt;8a5c552&lt;/a&gt;&lt;/strong&gt;. You may also be interested in checking a &lt;a href="https://github.com/CharlesAracil/webpack-vue-django" rel="noopener noreferrer"&gt;vue project template that CharlesAracil&lt;/a&gt; created taking inspiration from this entry.&lt;/p&gt;

&lt;p&gt;I recently started a new web project based on both Django and Vuejs. It took a good deal of reading half-related and/or outdated posts, tons of documentation, and a good deal of trial and error to get it right.&lt;/p&gt;

&lt;p&gt;In this post we will cover the key points on &lt;strong&gt;setting up a nice and solid development environment that is consisten with production and hence easy to deploy&lt;/strong&gt;. The specifics of how to deploy, final configuration touches and (automation) will be discussed in a future article.&lt;/p&gt;

&lt;p&gt;This is the solution that I found, there may be better alternatives (which I’d be happy to read) and it is utimately written with the intention of helping others as well as my future-self :)&lt;/p&gt;

&lt;h3&gt;
  
  
  Continue reading at &lt;a href="https://ariera.github.io/2017/09/26/django-webpack-vue-js-setting-up-a-new-project-that-s-easy-to-develop-and-deploy-part-1.html" rel="noopener noreferrer"&gt;ariera.github.io&lt;/a&gt;
&lt;/h3&gt;

</description>
      <category>django</category>
      <category>vue</category>
      <category>webpack</category>
      <category>webdev</category>
    </item>
    <item>
      <title>dev-toolbar a web developer’s best friend!</title>
      <dc:creator>Alejandro Riera</dc:creator>
      <pubDate>Wed, 20 Sep 2017 16:05:28 +0000</pubDate>
      <link>https://dev.to/ariera/dev-toolbar-a-web-developers-best-friend</link>
      <guid>https://dev.to/ariera/dev-toolbar-a-web-developers-best-friend</guid>
      <description>&lt;p&gt;The &lt;strong&gt;dev-toolbar&lt;/strong&gt; is a simple concept we came up with many years ago. The idea is to provide developers with a toolbelt full of tricks (shortcuts, toggles, login-as…) hidden in the frontend. It is such an integral part of my workflow that it is usually the first thing I set up in any project.&lt;/p&gt;

&lt;p&gt;In this entry we will see how to set it up in a Django web application. We will focus on &lt;strong&gt;the feature that everybody loves&lt;/strong&gt; : the ability to login as any user in the database (great time saver). We call it &lt;strong&gt;impersonate&lt;/strong&gt; , and this is how it looks like:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/http%3A%2F%2Fariera.github.io%2Fassets%2Fdev-toolbar.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/http%3A%2F%2Fariera.github.io%2Fassets%2Fdev-toolbar.png" alt="developer toolbar"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A simple select with all the users in your database. Click on one and you’ll be logged in as him/her.&lt;/p&gt;

&lt;p&gt;Let’s get on with it!&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Create a dev app
&lt;/h3&gt;

&lt;p&gt;We will start by creating a new app that we will call &lt;code&gt;dev&lt;/code&gt;. It will hold all of our impersonation logic, but is also a useful place to have to keep a style guide for developers, or some handy snippets to share accross the team, or maybe just to house a temporary experiment.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;python manage.py startapp dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and don’t forget to add it to your &lt;code&gt;INSTALLED_APPS&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# ./your_app/settings.py
&lt;/span&gt;&lt;span class="n"&gt;INSTALLED_APPS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
  &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;dev.apps.DevConfig&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="c1"&gt;# ...
&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. The view and urls
&lt;/h3&gt;

&lt;p&gt;Here we will control if the current user is allowed to impersonate or not, and perform the actual impersonation. In this case we are allowing any superuser to login as any other user, but you may choose any other criteria, for example only in development environment, or only if &lt;code&gt;DEBUG&lt;/code&gt; is &lt;code&gt;True&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# ./dev/views.py
from django.shortcuts import redirect, render, get_object_or_404
from django.contrib.auth import get_user_model, login
from django.http import Http404

def impersonate(request, user_id):
  current_user = request.user
  if current_user.is_superuser:
    user = get_object_or_404(get_user_model(), pk=user_id)
    login(request, user)
    return redirect('/dev')
  else:
    raise Http404("Impersonate is only available for superusers")
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# ./dev/urls.py
from django.conf.urls import url
from . import views

app_name = 'dev'
urlpatterns = [
    url(r'^$', views.index, name='index'),
    url(r'^impersonate/(?P&amp;lt;user_id&amp;gt;[0-9]+)/$', views.impersonate, name='impersonate'),
]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# ./your_app/urls.py
from django.conf.urls import include, url
from django.contrib import admin

urlpatterns = [
    url(r'^dev/', include('dev.urls')),
    url(r'^admin/', admin.site.urls),
]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3. Template tag
&lt;/h3&gt;

&lt;p&gt;We want to reuse our toolbar across many templates so we will extract it into it’s own template tag, using &lt;a href="https://docs.djangoproject.com/en/1.11/howto/custom-template-tags/#inclusion-tags" rel="noopener noreferrer"&gt;Django’s inclusion-tags&lt;/a&gt; functionality.&lt;/p&gt;

&lt;p&gt;For that you need to create this directory: &lt;code&gt;./dev/templatetags&lt;/code&gt; and an empty &lt;code&gt;__init__.py&lt;/code&gt; file inside of it.&lt;/p&gt;

&lt;p&gt;Inside our templatetags folder we will create the following file, which acts like the view of our new &lt;code&gt;dev_toolbar&lt;/code&gt; templatetag. Notice 2 things:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;First we are linking it to the template &lt;code&gt;dev/toolbar.html&lt;/code&gt; that we will define later.&lt;/li&gt;
&lt;li&gt;And second we use &lt;code&gt;takes_context=True&lt;/code&gt; to be able to access to the current user. This will allow us to do some basic authorization (ie. only superusers are allowed to use this feature). This is redundant with the logic we defined before, but it’s good to have a safety net when you’re handling delicate data.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# ./dev/templatetags/dev_toolbar.py
from django.contrib.auth import get_user_model
from django import template

register = template.Library()

@register.inclusion_tag('dev/toolbar.html', takes_context=True)
def dev_toolbar(context):
  request = context['request']
  current_user = request.user
  if current_user.is_superuser:
    users = get_user_model().objects.all()
  else:
    users = []
  return {'users': users, 'current_user': current_user}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The template file contains its own css, javascript and html. Some simple positioning and styling and bit of css+js logic to make the bar more subtle.&lt;/p&gt;

&lt;p&gt;We will render a select box with all the users in the database and a javascript will take care of calling the impersonate action whenever we choose another user other than ourselves. Two more handy links to &lt;code&gt;/dev&lt;/code&gt; and &lt;code&gt;/admin&lt;/code&gt; areas are included.&lt;/p&gt;

&lt;p&gt;Last, but not least, I usually include a small close button, it comes in handy sometimes when doing CSS work, you just want to get rid of the bar.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;!-- ./dev/templates/dev/toolbar.html --&amp;gt;
{% if current_user.is_superuser %}
&amp;lt;style&amp;gt;
  #dev-toolbar{
    background-color: #ccc;
    position: fixed;
    bottom: 0;
    right: 0;
    padding: 5px;
  }
  #dev-toolbar.subtle {
    opacity: 0.2;
  }
&amp;lt;/style&amp;gt;
&amp;lt;script&amp;gt;
  window.dev = {
    closeToolbar: function closeToolbar(){
      var toolbar = document.getElementById("dev-toolbar")
      toolbar.parentElement.removeChild(toolbar)
    },
    showToolbar: function showToolbar(){
      var toolbar = document.getElementById("dev-toolbar")
      toolbar.classList.remove("subtle");
    },
    impersonate: function impersonate() {
      var select = document.getElementById("dev-impersonate")
      window.location = select.value
    }
  }
&amp;lt;/script&amp;gt;
&amp;lt;div id="dev-toolbar" class="subtle" onmouseover="dev.showToolbar()"&amp;gt;
  &amp;lt;small&amp;gt;&amp;lt;a href="/dev"&amp;gt;dev&amp;lt;/a&amp;gt;&amp;lt;/small&amp;gt;
  &amp;lt;small&amp;gt;&amp;lt;a href="/admin"&amp;gt;admin&amp;lt;/a&amp;gt;&amp;lt;/small&amp;gt;

  {% if users %}
    &amp;lt;select id="dev-impersonate" onchange="dev.impersonate()"&amp;gt;
      {% for user in users %}
         &amp;lt;option value="{% url 'dev:impersonate' user.id %}"
             {% if user == current_user %}selected="selected"{% endif %}&amp;gt;
             {{user.email}}
         &amp;lt;/option&amp;gt;
      {% endfor %}
    &amp;lt;/select&amp;gt;
  {% endif %}

  &amp;lt;button id="dev-close-toolbar" onclick="dev.closeToolbar()"&amp;gt;X&amp;lt;/button&amp;gt;
&amp;lt;/div&amp;gt;
{% endif %}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  4. Using it
&lt;/h3&gt;

&lt;p&gt;Our feature is complete and ready to be used. Simply load it in any view and call it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{% load dev_toolbar %}
{% dev_toolbar %}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  5. Show it in the admin panel
&lt;/h3&gt;

&lt;p&gt;We are going to override the default &lt;code&gt;admin/index.html&lt;/code&gt; template and include our new &lt;code&gt;dev_toolbar&lt;/code&gt; snippet. For that we need to create a generic &lt;code&gt;./templates&lt;/code&gt; directory at the root of the project and add it to &lt;code&gt;TEMPLATES['DIRS']&lt;/code&gt; in the settings of the project.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# ./your_app/settings.py
&lt;/span&gt;&lt;span class="n"&gt;TEMPLATES&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;DIRS&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;BASE_DIR&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;templates&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)],&lt;/span&gt;
    &lt;span class="c1"&gt;# ...
&lt;/span&gt;  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And now create a new file to override the default administration index tempalte.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;!-- ./templates/admin/index.html --&amp;gt;
    {% extends "admin/index.html" %}
    {% load dev_toolbar %}

    {% block sidebar %}
        {{block.super}}
        {% dev_toolbar %}
    {% endblock %}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  References
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://docs.djangoproject.com/en/1.11/topics/http/views/#the-http404-exception" rel="noopener noreferrer"&gt;Django Http404&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.djangoproject.com/en/1.11/howto/custom-template-tags/#inclusion-tags" rel="noopener noreferrer"&gt;Django inclusion-tags&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://stackoverflow.com/questions/6713022/handling-request-in-django-inclusion-template-tag" rel="noopener noreferrer"&gt;SO: Handling request in django inclusion template tag&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://stackoverflow.com/a/6586068" rel="noopener noreferrer"&gt;SO: How to override and extend basic Django admin templates?&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;This post was originally published on &lt;a href="http://ariera.github.io/2017/09/20/dev-toolbar-a-web-developers-best-friend.html" rel="noopener noreferrer"&gt;ariera.github.io&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>django</category>
      <category>python</category>
      <category>webdev</category>
    </item>
    <item>
      <title> "How to use email as user identifier in Django 1.11"</title>
      <dc:creator>Alejandro Riera</dc:creator>
      <pubDate>Wed, 20 Sep 2017 08:55:28 +0000</pubDate>
      <link>https://dev.to/ariera/how-to-use-email-as-user-identifier-in-django-111</link>
      <guid>https://dev.to/ariera/how-to-use-email-as-user-identifier-in-django-111</guid>
      <description>&lt;p&gt;&lt;small&gt;&lt;br&gt;
&lt;em&gt;&lt;a href="https://ariera.github.io/2017/09/20/how-to-use-email-as-user-identifier-in-django-1-11.html"&gt;(This post was originally published on ariera.github.io)&lt;/a&gt;&lt;/em&gt;&lt;br&gt;
&lt;/small&gt;&lt;/p&gt;

&lt;p&gt;I found several guides and tips on how to do this. They were all very inspiring and helpful but I had to figure some things on my own because none of them provided all I needed: a fully working admin panel that replicates all the functionality of the original one.&lt;/p&gt;

&lt;p&gt;I won't stop to explain what every line is doing, in the end I'm just trying to save myself some trouble in the future, but I share it because it may be useful to someone else as well. At the moment of writing this I am using &lt;code&gt;Django==1.11.5&lt;/code&gt;.&lt;/p&gt;
&lt;h4&gt;
  
  
  Before we start
&lt;/h4&gt;

&lt;p&gt;Remember that you need to do this at the beginning of the life of your project, before running any migrations, so drop&amp;amp;create your DB if you are already that far. I would do this in my local machine with postgres:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pg_ctl -D /usr/local/var/postgres restart
dropdb my_app
createdb my_app
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  First create your new app
&lt;/h4&gt;

&lt;p&gt;Since it this is gonna be very generic, project-wide app, I like to call it &lt;code&gt;base&lt;/code&gt;. I may end up placing other basic models / views in here.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;python&lt;/span&gt; &lt;span class="n"&gt;manage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;py&lt;/span&gt; &lt;span class="n"&gt;startapp&lt;/span&gt; &lt;span class="n"&gt;base&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Configure your settings
&lt;/h4&gt;

&lt;p&gt;./my_app/settings.py&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# ./my_app/settings.py
AUTH_USER_MODEL = 'base.User'
INSTALLED_APPS = [
    'base.apps.BaseConfig',
    # ...
]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Configure your &lt;code&gt;models&lt;/code&gt; and &lt;code&gt;admin&lt;/code&gt;
&lt;/h4&gt;

&lt;p&gt;This will be your models, highly inspired by the &lt;a href="https://github.com/django/django/blob/a96b981d84367fd41b1df40adf3ac9ca71a741dd/django/contrib/auth/models.py#L288"&gt;original Django source code&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;./base/models.py&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;from django.db import models
from django.contrib.auth.models import AbstractBaseUser
from django.contrib.auth.models import BaseUserManager
from django.contrib.auth.models import PermissionsMixin
from django.utils.translation import ugettext_lazy as _

class MyUserManager(BaseUserManager):
    """
    A custom user manager to deal with emails as unique identifiers for auth
    instead of usernames. The default that's used is "UserManager"
    """
    def _create_user(self, email, password, **extra_fields):
        """
        Creates and saves a User with the given email and password.
        """
        if not email:
            raise ValueError('The Email must be set')
        email = self.normalize_email(email)
        user = self.model(email=email, **extra_fields)
        user.set_password(password)
        user.save()
        return user

    def create_superuser(self, email, password, **extra_fields):
        extra_fields.setdefault('is_staff', True)
        extra_fields.setdefault('is_superuser', True)
        extra_fields.setdefault('is_active', True)

        if extra_fields.get('is_staff') is not True:
            raise ValueError('Superuser must have is_staff=True.')
        if extra_fields.get('is_superuser') is not True:
            raise ValueError('Superuser must have is_superuser=True.')
        return self._create_user(email, password, **extra_fields)



class User(AbstractBaseUser, PermissionsMixin):
    email = models.EmailField(unique=True, null=True)
    is_staff = models.BooleanField(
        _('staff status'),
        default=False,
        help_text=_('Designates whether the user can log into this site.'),
    )
    is_active = models.BooleanField(
        _('active'),
        default=True,
        help_text=_(
            'Designates whether this user should be treated as active. '
            'Unselect this instead of deleting accounts.'
        ),
    )
    is_superuser = models.BooleanField(default=False, help_text='Designates that this user has all permissions without explicitly assigning them.', verbose_name='superuser status')
    created_at   = models.DateTimeField(auto_now_add=True)
    updated_at   = models.DateTimeField(auto_now=True)
    first_name   = models.CharField(blank=True, max_length=30, verbose_name='first name')
    last_name    = models.CharField(blank=True, max_length=30, verbose_name='last name')

    USERNAME_FIELD = 'email'
    objects = MyUserManager()

    def __str__(self):
        return self.email

    def get_full_name(self):
        return self.email

    def get_short_name(self):
        return self.email

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And here is the admin file, also highly inspired by the &lt;a href="https://github.com/django/django/blob/a96b981d84367fd41b1df40adf3ac9ca71a741dd/django/contrib/auth/admin.py#L42"&gt;original Django source code&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;./base/admin.py&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;from django import forms
from django.contrib import admin
from django.contrib.auth import password_validation
from django.contrib.auth.admin import UserAdmin as BaseUserAdmin
from django.contrib.auth.forms import ReadOnlyPasswordHashField
from django.contrib.auth.forms import UserChangeForm as BaseUserChangeForm
from django.utils.translation import gettext, gettext_lazy as _
from .models import User

class UserCreationForm(forms.ModelForm):
    """A form for creating new users. Includes all the required
    fields, plus a repeated password."""
    password1 = forms.CharField(
        label=_("Password"),
        strip=False,
        widget=forms.PasswordInput,
        help_text=password_validation.password_validators_help_text_html(),
    )
    password2 = forms.CharField(
        label=_("Password confirmation"),
        widget=forms.PasswordInput,
        strip=False,
        help_text=_("Enter the same password as before, for verification."),
    )


    class Meta:
        model = User
        fields = ('email', 'is_staff', 'is_active', 'first_name', 'last_name', )

    def clean_password2(self):
        # Check that the two password entries match
        password1 = self.cleaned_data.get("password1")
        password2 = self.cleaned_data.get("password2")
        if password1 and password2 and password1 != password2:
            raise forms.ValidationError("Passwords don't match")
        return password2

    def save(self, commit=True):
        # Save the provided password in hashed format
        user = super().save(commit=False)
        user.set_password(self.cleaned_data["password1"])
        if commit:
            user.save()
        return user

class UserChangeForm(BaseUserChangeForm):
    """
    Override as needed
    """

class UserAdmin(BaseUserAdmin):
    # The forms to add and change user instances
    form = UserChangeForm
    add_form = UserCreationForm

    # The fields to be used in displaying the User model.
    # These override the definitions on the base UserAdmin
    # that reference specific fields on auth.User.
    list_display = ('email', 'is_superuser', 'is_staff', 'is_active', 'first_name', 'last_name', 'created_at', 'updated_at', 'last_login')
    # list_filter = ('email',)

    readonly_fields=('created_at', 'updated_at',)
    fieldsets = (
        (None                , {'fields': ('email', 'password')}),
        (_('Personal info')  , {'fields': ('first_name', 'last_name',)}),
        (_('Permissions')    , {'fields': ('is_active', 'is_staff', 'is_superuser', 'groups', 'user_permissions')}),
        (_('Important dates'), {'fields': ('last_login', 'created_at', 'updated_at')}),
    )
    # add_fieldsets is not a standard ModelAdmin attribute. UserAdmin
    # overrides get_fieldsets to use this attribute when creating a user.
    add_fieldsets = (
        (None, {
            'classes': ('wide',),
            'fields': ('email', 'password1', 'password2')}
        ),
    )
    search_fields = ('email',)
    ordering = ('email',)
    # filter_horizontal = ()


admin.site.register(User, UserAdmin)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Apply changes
&lt;/h4&gt;

&lt;p&gt;And lastly you need to generate your migrations and migrate&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;python manage.py makemigrations base
python manage.py migrate
python manage.py createsuperuser
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  References
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://docs.djangoproject.com/en/1.11/topics/auth/customizing/#substituting-a-custom-user-model"&gt;https://docs.djangoproject.com/en/1.11/topics/auth/customizing/#substituting-a-custom-user-model&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.djangoproject.com/en/1.11/topics/auth/customizing/#a-full-example"&gt;https://docs.djangoproject.com/en/1.11/topics/auth/customizing/#a-full-example&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://medium.com/@ramykhuffash/django-authentication-with-just-an-email-and-password-no-username-required-33e47976b517"&gt;https://medium.com/@ramykhuffash/django-authentication-with-just-an-email-and-password-no-username-required-33e47976b517&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://stackoverflow.com/questions/3967644/django-admin-how-to-display-a-field-that-is-marked-as-editable-false-in-the-mo/3967891#3967891"&gt;https://stackoverflow.com/questions/3967644/django-admin-how-to-display-a-field-that-is-marked-as-editable-false-in-the-mo/3967891#3967891&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>django</category>
      <category>python</category>
    </item>
    <item>
      <title>Setting up GitLab’s Continuous Integration with Laravel, PostgreSQL and PHPUnit</title>
      <dc:creator>Alejandro Riera</dc:creator>
      <pubDate>Thu, 09 Mar 2017 17:06:56 +0000</pubDate>
      <link>https://dev.to/ariera/setting-up-gitlabs-continuous-integration-with-laravel-postgresql-and-phpunit</link>
      <guid>https://dev.to/ariera/setting-up-gitlabs-continuous-integration-with-laravel-postgresql-and-phpunit</guid>
      <description>&lt;p&gt;I recently set up a continuous integration process based on GitLab for a project based on Laravel and PostgreSQL. It took a while to get it right, so I am sharing here my final config.&lt;/p&gt;

&lt;h2&gt;
  
  
  Basic structure
&lt;/h2&gt;

&lt;p&gt;The main GitLab CI configuration is held by a file at the root of your project that should be called &lt;code&gt;.gitlab-ci.yml&lt;/code&gt;. From this file it is possible to call other shell scripts, but I have tried to hold up everything in just one place.&lt;/p&gt;

&lt;p&gt;We will however manage a second file called &lt;code&gt;.env.gitlab-ci&lt;/code&gt; that will hold all ENV variable configuration optios specific to GitLab CI.&lt;/p&gt;

&lt;p&gt;Last but not least you will need a PHPUnit xml configuration file.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step by step look into &lt;code&gt;.gitlab-ci.yml&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;We’ll go line by line in the config file, but you can see the final result at the end of the article.&lt;/p&gt;

&lt;p&gt; &lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;image: php:7.0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here we select one of the available docker images with php already configured. You can find a complete list here: from &lt;a href="https://hub.docker.com/r/%5C_/php/"&gt;https://hub.docker.com/r/\_/php/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt; &lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;services:
  - postgres:latest
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;From GitLab’s official documentation &lt;a href="https://docs.gitlab.com/ce/ci/docker/using_docker_images.html#what-is-a-service"&gt;src&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The &lt;code&gt;services&lt;/code&gt; keyword defines just another docker image that is run during your job and is linked to the docker image that the &lt;code&gt;image&lt;/code&gt; keyword defines. This allows you to access the service image during build time.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It is &lt;strong&gt;very important&lt;/strong&gt; to remark that if you add &lt;code&gt;postgres&lt;/code&gt; as service to your application, the service container for PostgresSQL will be accessible under the hostname &lt;code&gt;postgres&lt;/code&gt;. So, in order to access your database service you have to connect to the host named &lt;code&gt;postgres&lt;/code&gt; instead of a socket or &lt;code&gt;localhost&lt;/code&gt;. This will be important later when we configure our &lt;code&gt;.env.gitlab-ci&lt;/code&gt; file.&lt;/p&gt;

&lt;p&gt; &lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;variables:
  POSTGRES_DB: mydb-test
  POSTGRES_USER: runner
  POSTGRES_PASSWORD: ""
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here you may use all the values you want as long as they match with those of &lt;code&gt;.env.gitlab-ci&lt;/code&gt; and your &lt;code&gt;phpunit.xml&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt; &lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;before_script:
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Again from the official documentation &lt;a href="https://docs.gitlab.com/ce/ci/yaml/README.html#before_script"&gt;src&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;before_script&lt;/code&gt; is used to define the command that should be run before all jobs, including deploy jobs, but after the restoration of artifacts. This can be an array or a multi-line string.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Lets explore all these commands one by one.&lt;/p&gt;

&lt;p&gt; &lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;- &amp;gt;
  set -xe
  &amp;amp;&amp;amp; apt-get update -yqq
  &amp;amp;&amp;amp; apt-get install -yqq
  git
  libicu-dev
  libpq-dev
  libzip-dev
  zlib1g-dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Simply installing some dependencies&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;git&lt;/code&gt; is needed to later install &lt;code&gt;composer&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;libicu-dev&lt;/code&gt; will be necessary for the internationalization php extension (&lt;code&gt;intl&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;libpq-dev&lt;/code&gt; are the header files for postgres&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;libzip-dev&lt;/code&gt; and &lt;code&gt;zlib1g-dev&lt;/code&gt; are necessary for zip manipulation and needed to activate the corresponding php extension. Without them our &lt;code&gt;composer install&lt;/code&gt; command will throw a lot of warnings and try to download each package twice &lt;strong&gt;slowing the whol process down for 2 or more minutes&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt; &lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;- &amp;gt;
  docker-php-ext-install
  pdo_pgsql
  pgsql
  sockets
  intl
  zip
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;docker-php-ext-install&lt;/code&gt; is a handy script for installing php extensions provided by the official php docker image. I restricted myself to the bare minimun of extension necessary for my project to run. You may need more.&lt;/p&gt;

&lt;p&gt; &lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;- curl -sS https://getcomposer.org/installer | php
- php composer.phar self-update
- php composer.phar install --no-progress --no-interaction
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Install &lt;code&gt;composer&lt;/code&gt; and use it to install all of our project dependencies.&lt;/p&gt;

&lt;p&gt; &lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;- cp .env.gitlab-ci .env
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Set up the correct ENV variables. We’ll look into this file in a moment.&lt;/p&gt;

&lt;p&gt; &lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;- php artisan key:generate
- php artisan help config:clear
- php artisan route:clear
- php artisan migrate:refresh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Set application key, clear a couple of caches just in case and run the migrations.&lt;/p&gt;

&lt;p&gt; &lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;test:app:
  script:
  - vendor/bin/phpunit --configuration phpunit-gitlabci.xml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And finally run our PHPUnit test suite using our &lt;code&gt;phpunit-gitlabci.xml&lt;/code&gt; config file.&lt;/p&gt;

&lt;h2&gt;
  
  
  Small break
&lt;/h2&gt;

&lt;p&gt;That was the most complicated file, the rest is a piece of cake, but you deserve a rest :P&lt;/p&gt;

&lt;p&gt; &lt;/p&gt;

&lt;h2&gt;
  
  
  A brief look into &lt;code&gt;.env.gitlab-ci&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;The file itself is quite self explainatory, and you can see the final version at the end of the article. But I wanted to highlight the database configuration.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;DB_CONNECTION=pgsql
DB_PORT=5432
DB_HOST=postgres
DB_DATABASE=mydb-test
DB_USERNAME=runner
DB_PASSWORD=
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notice how the values for &lt;code&gt;DB_HOST&lt;/code&gt;, &lt;code&gt;DB_DATABASE&lt;/code&gt; and &lt;code&gt;DB_USERNAME&lt;/code&gt; are the same as those of inside of the &lt;code&gt;variables&lt;/code&gt; key on the &lt;code&gt;.gitlab-ci.yml&lt;/code&gt; configuration file.&lt;/p&gt;

&lt;p&gt; &lt;/p&gt;

&lt;h2&gt;
  
  
  A brief note on &lt;code&gt;phpunit-gitlabci.xml&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;This file may be optional depending on your local configuration. If your normal &lt;code&gt;phpunit.xml&lt;/code&gt; file doesn’t define any &lt;code&gt;DB_DATABASE&lt;/code&gt; env variable you would not need this. But if it happens to define one, and has a different value from that that you chose for GitLab’s CI you have to remember to set it correctly:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;env name="DB_DATABASE" value="mydb-test"/&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt; &lt;/p&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;GitLab’s continuous integration system can be a blessing once is properly configured, but it can get a bit confusing if you trail off of the usual path and all you hear is &lt;em&gt;docker image configuration linking&lt;/em&gt; and you’ve never worked with it before. Hopefully you’ll find this small guide useful  &lt;/p&gt;

&lt;p&gt;.gitlab-ci.yml&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;image: php:7.0
services:
  - postgres:latest
variables:
  POSTGRES_DB: mydb-test
  POSTGRES_USER: runner
  POSTGRES_PASSWORD: ""

before_script:
- &amp;gt;
  set -xe
  &amp;amp;&amp;amp; apt-get update -yqq
  &amp;amp;&amp;amp; apt-get install -yqq
  git
  libicu-dev
  libpq-dev
  libzip-dev
  zlib1g-dev
- &amp;gt;
  docker-php-ext-install
  pdo_pgsql
  pgsql
  sockets
  intl
  zip
- curl -sS https://getcomposer.org/installer | php
- php composer.phar self-update
- php composer.phar install --no-progress --no-interaction
- cp .env.gitlab-ci .env
- php artisan key:generate
- php artisan help config:clear
- php artisan route:clear
- php artisan migrate:refresh

test:app:
  script:
  - vendor/bin/phpunit --configuration phpunit-gitlabci.xml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt; &lt;/p&gt;

&lt;p&gt;.env.gitlab-ci&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;APP_ENV=testing
APP_KEY=key
APP_DEBUG=true
APP_LOG_LEVEL=debug
APP_URL=http://localhost:8000

DB_CONNECTION=pgsql
DB_HOST=postgres
DB_PORT=5432
DB_DATABASE=mydb-test
DB_USERNAME=runner
DB_PASSWORD=

BROADCAST_DRIVER=log
CACHE_DRIVER=array
SESSION_DRIVER=array
QUEUE_DRIVER=sync
MAIL_DRIVER=log
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;This post was originally published on &lt;a href="http://ariera.github.io/2017/03/09/settingup-gitlab-ci-with-laravel-postgres-phpunit.html"&gt;ariera.github.io&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>laravel</category>
      <category>postgres</category>
      <category>gitlab</category>
      <category>ci</category>
    </item>
    <item>
      <title>Using Postgre’s UUIDs in Laravel and Eloquent</title>
      <dc:creator>Alejandro Riera</dc:creator>
      <pubDate>Wed, 01 Mar 2017 18:06:56 +0000</pubDate>
      <link>https://dev.to/ariera/using-postgres-uuids-in-laravel-and-eloquent</link>
      <guid>https://dev.to/ariera/using-postgres-uuids-in-laravel-and-eloquent</guid>
      <description>&lt;p&gt;One of the things I love from postgres is the ability use &lt;strong&gt;UUIDs as primary keys&lt;/strong&gt;. &lt;a href="https://tomharrisonjr.com/uuid-or-guid-as-primary-keys-be-careful-7b2aa3dcb439#.poi02at77"&gt;Tom Harrison Jr. wrote recently a summary worth reading about the pros and cons of this approach&lt;/a&gt;. For me the pros outweight the cons, but that’s something you may have to decide by your own and on a project basis.&lt;/p&gt;

&lt;p&gt;However, if you decide to go for it and you are using Laravel you’ll be surprised to see that getting UUIDs to work &lt;strong&gt;is not as easy as the official documentation makes you think.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The following is a small cheatsheet for the things you have to take care of&lt;/p&gt;

&lt;h2&gt;
  
  
  Setting up the db
&lt;/h2&gt;

&lt;p&gt;The first thing you need is to activate the UUID extension in postgres. Simply create a new migration that looks like this:&lt;/p&gt;

&lt;p&gt;database/migrations/1900_01_01_000001_add_uuid_extension_to_postgresql.php&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
use Illuminate\Support\Facades\DB;

class AddUuidExtensionToPostgresql extends Migration
{

    public function up()
    {
        DB::statement('CREATE EXTENSION IF NOT EXISTS "uuid-ossp";');
    }

    public function down()
    {
        DB::statement('DROP EXTENSION IF EXISTS "uuid-ossp";');
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Migrations
&lt;/h2&gt;

&lt;p&gt;Let’s say you want to have a &lt;code&gt;users&lt;/code&gt; table. You probably want your &lt;code&gt;id&lt;/code&gt;s to be automatically generated. Most of the tutorials I have found rely on &lt;code&gt;beforeCreate&lt;/code&gt; callbacks on the model, at the applications level. I think it is best if the database takes care of this.&lt;/p&gt;

&lt;p&gt;Unfortunately the nice &lt;code&gt;Schema&lt;/code&gt; DSL doesn’t provide a way to do this, so we need to use plain SQL for it.&lt;/p&gt;

&lt;p&gt;database/migrations/2017_03_01_000001_create_users.php&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;?php
Schema::create('users', function (Blueprint $table) {
    $table-&amp;gt;uuid('id');
    $table-&amp;gt;primary('id');
    // ...
});
DB::statement('ALTER TABLE users ALTER COLUMN id SET DEFAULT uuid_generate_v4();');
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Models
&lt;/h2&gt;

&lt;p&gt;Now let’s create the corresponding &lt;code&gt;User&lt;/code&gt; model.&lt;/p&gt;

&lt;p&gt;App/User.php&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class User extends Model
{
  protected $casts = [
    'id' =&amp;gt; 'string'
  ];
  protected $primaryKey = "id";
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Couple of caveats here. First you need to &lt;strong&gt;make sure that your primary key is typecasted as &lt;code&gt;string&lt;/code&gt;&lt;/strong&gt; , otherwise it will be typecasted to &lt;code&gt;integer&lt;/code&gt; giving you all sorts of funny errors.&lt;/p&gt;

&lt;p&gt;Second: in this example I am naming my primary key &lt;code&gt;id&lt;/code&gt;, which is Eloquent’s default name. So overriding the &lt;code&gt;$primaryKey&lt;/code&gt; in this particular example is not very interesting, but many people opt for naming their pks &lt;code&gt;uuid&lt;/code&gt;, so pay attention to that if that’s your case.&lt;/p&gt;

&lt;p&gt;Lastly, many comments online and tutorials indicate that the public attribute &lt;code&gt;$incrementing&lt;/code&gt; should be set to &lt;code&gt;false&lt;/code&gt;, arguing that UUIDs don’t need to be autoincremented. As much sense as that might make it managed to broke my applications. &lt;strong&gt;Disabling the incrementing property somehow nullifies the &lt;code&gt;id&lt;/code&gt; attribute in newly created records&lt;/strong&gt; , as the following code highlights.&lt;/p&gt;

&lt;p&gt;App/User.php&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;?php
class User extends Model
{
  public $incrementing = false;
  // ...
}

$user = new User;
$user-&amp;gt;save();
$user-&amp;gt;id; /* =&amp;gt; null */
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;Having UUIDs as primary keys for your records can be tricky to do right on Laravel for the first time. Hopefully this tips will help you avoid the beginners gotchas that I fell on :D&lt;/p&gt;

&lt;p&gt;&lt;em&gt;This post was originally published on &lt;a href="http://ariera.github.io/2017/03/01/using-postgres-uuids-with-laravel.html"&gt;ariera.github.io&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>postgres</category>
      <category>laravel</category>
      <category>php</category>
      <category>uuid</category>
    </item>
  </channel>
</rss>
