====== Django Models ======
===== Migrations =====
$ python manage.py makemigrations
Will create migration files for all the apps if the ''app'' was not indicated.
$ python manage.py migrate
Will apply migrations to the configured DB.
===== Signals =====
==== Ways to connect signals ====
class Award(models.Model):
name = models.CharField(max_length=200, unique=True)
...
@classmethod
def pre_save(cls, sender, instance, **kwargs):
...
pre_save.connect(Award.pre_save, sender=Award)
from django.contrib.auth.models import User
from django.db.models.signals import post_save
from django.dispatch import receiver
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
bio = models.TextField(max_length=500, blank=True)
location = models.CharField(max_length=30, blank=True)
birth_date = models.DateField(null=True, blank=True)
@receiver(post_save, sender=User)
def create_user_profile(sender, instance, created, **kwargs):
if created:
Profile.objects.create(user=instance)
@receiver(post_save, sender=User)
def save_user_profile(sender, instance, **kwargs):
instance.profile.save()
===== Model configuration =====
==== Modelos proxy ====
Proxy models are used to modify Python behaviour of a model by extending a model class. Database tables aren't generated for proxy models. So you can't use a proxy model for AUTH_USER_MODEL.
class Badge(models.Model):
name = ...
color = ... # gold/silver
class GoldBadge(Badge)
class Meta:
proxy = True
def award(self, user):
# award a gold badge to user
class SilverBadge(Badge):
class Meta:
proxy = True
def award(self, user):
# award a silver badge to user
===== Fields =====
==== DateTime Field ====
The auto_now_add will set the timezone.now() only when the instance is created, and auto_now will update the field everytime the save method is called.
class Invoice(models.Model):
description = models.CharField(max_length=255)
status = models.CharField(max_length=10)
vendor = models.ForeignKey(Vendor)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
==== Image Field ====
Model:
cover = models.ImageField(null=True)
Template:
{% if object.cover %}
{% endif %}
Config:
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, '../media')
Urls:
from django.contrib.staticfiles.urls import static
from django.conf import settings
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
==== Choice ====
from django.db import models
class Person(models.Model):
SHIRT_SIZES = (
('S', 'Small'),
('M', 'Medium'),
('L', 'Large'),
)
name = models.CharField(max_length=60)
shirt_size = models.CharField(max_length=2, choices=SHIRT_SIZES)
Get its values
>>> p = Person(name="Fred Flintstone", shirt_size="L")
>>> p.save()
>>> p.shirt_size
'L'
>>> p.get_shirt_size_display()
'Large'
==== Special fields ====
id = models.UUIDField(primary_key=True, default=uuid4, help_text="Unique ID for this particular video")
==== Fields configuration ====
=== Choice ===
import calendar
...
class MyModel(models.Model):
...
MONTH_CHOICES = [(str(i), calendar.month_name[i]) for i in range(1,13)]
month = CharField(max_length=9, choices=MONTHS_CHOICES, default='1')
===== How to... =====
==== Deal with performed queries ====
See the current registered queries (with their times):
from django.db import connection
connection.queries
See a concrete database queries:
from django.db import connections
connections['my_db_alias'].queries
Delete the query array:
from django.db import reset_queries
reset_queries()
==== Get an app model ====
from django.apps import apps
apps.get_model('users', 'BaseUser')
==== Choose a random element from DB ====
reg = Work(title=random_string_generator(random.randint(5, 15), True),
license=License.objects.order_by('?').first(),
description=random_string_generator(random.randint(200,2000), True),
created=str_time_prop(prop=random.random()),
creator=User.objects.order_by('?').first())
reg.save()
==== Clean migrations ====
find . -path "*/migrations/*.py" -not -name "__init__.py" -delete
find . -path "*/migrations/*.pyc" -delete
=== Script to reset the whole DB ===
#!/bin/sh
export PGPASSWORD=mysecretpassword
export DATABASE=puma
find . -path "*/migrations/*.py" -not -name "__init__.py" -delete
find . -path "*/migrations/*.pyc" -delete
dropdb -h 127.0.0.1 -U postgres $DATABASE
createdb -T template0 -h 127.0.0.1 -U postgres $DATABASE
python manage.py makemigrations
python manage.py migrate
psql -h 127.0.0.1 -U postgres -d $DATABASE -c "INSERT INTO public.pumapp_user (password,last_login,is_superuser,username,first_name,last_name,is_staff,is_active,date_joined,email,current_project_id) VALUES ('pbkdf2_sha256$100000$8RoYX0VMbGIY$OZrZowL8A4pR/wgE/ggy7KOSAU82068MEG3tiZHV70I=',NULL,true,'admin','','',true,true,'2019-01-31 08:22:29.609','admin@a.com',NULL);"
psql -h 127.0.0.1 -U postgres -d $DATABASE -c "INSERT INTO public.redmine_auth_redmineconfig (url) VALUES ('https://redmine.gtd.es');"