Muestra las diferencias entre dos versiones de la página.
| Ambos lados, revisión anterior Revisión previa Próxima revisión | Revisión previa | ||
|
wiki2:python:django:models [2018/10/11 19:50] alfred [Get an app model] |
wiki2:python:django:models [2020/05/09 09:25] (actual) |
||
|---|---|---|---|
| Línea 1: | Línea 1: | ||
| ====== Django Models ====== | ====== Django Models ====== | ||
| + | ===== Migrations ===== | ||
| + | <code> | ||
| + | $ python manage.py makemigrations <app> | ||
| + | </code> | ||
| + | Will create migration files for all the apps if the ''app'' was not indicated. | ||
| + | |||
| + | <code> | ||
| + | $ python manage.py migrate | ||
| + | </code> | ||
| + | Will apply migrations to the configured DB. | ||
| + | ===== Signals ===== | ||
| + | |||
| + | ==== Ways to connect signals ==== | ||
| + | <code python> | ||
| + | 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) | ||
| + | </code> | ||
| + | <code python> | ||
| + | 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() | ||
| + | </code> | ||
| + | ===== Model configuration ===== | ||
| ==== Modelos proxy ==== | ==== Modelos proxy ==== | ||
| Línea 23: | Línea 68: | ||
| def award(self, user): | def award(self, user): | ||
| # award a silver badge to user | # award a silver badge to user | ||
| + | </code> | ||
| + | |||
| + | ===== 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. | ||
| + | |||
| + | <code python> | ||
| + | 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) | ||
| </code> | </code> | ||
| ==== Image Field ==== | ==== Image Field ==== | ||
| Línea 52: | Línea 110: | ||
| </code> | </code> | ||
| + | |||
| + | ==== Choice ==== | ||
| + | <code> | ||
| + | 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) | ||
| + | </code> | ||
| + | Get its values | ||
| + | <code> | ||
| + | >>> p = Person(name="Fred Flintstone", shirt_size="L") | ||
| + | >>> p.save() | ||
| + | >>> p.shirt_size | ||
| + | 'L' | ||
| + | >>> p.get_shirt_size_display() | ||
| + | 'Large' | ||
| + | </code> | ||
| ==== Special fields ==== | ==== Special fields ==== | ||
| Línea 57: | Línea 138: | ||
| id = models.UUIDField(primary_key=True, default=uuid4, help_text="Unique ID for this particular video") | id = models.UUIDField(primary_key=True, default=uuid4, help_text="Unique ID for this particular video") | ||
| </code> | </code> | ||
| + | |||
| + | ==== Fields configuration ==== | ||
| + | |||
| + | === Choice === | ||
| + | <code python> | ||
| + | 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') | ||
| + | </code> | ||
| + | |||
| + | |||
| ===== How to... ===== | ===== How to... ===== | ||
| + | ==== Deal with performed queries ==== | ||
| + | See the current registered queries (with their times): | ||
| + | <code> | ||
| + | from django.db import connection | ||
| + | connection.queries | ||
| + | </code> | ||
| + | |||
| + | See a concrete database queries: | ||
| + | <code> | ||
| + | from django.db import connections | ||
| + | connections['my_db_alias'].queries | ||
| + | </code> | ||
| + | |||
| + | Delete the query array: | ||
| + | <code> | ||
| + | from django.db import reset_queries | ||
| + | reset_queries() | ||
| + | </code> | ||
| ==== Get an app model ==== | ==== Get an app model ==== | ||
| <code> | <code> | ||
| from django.apps import apps | from django.apps import apps | ||
| apps.get_model('users', 'BaseUser') | apps.get_model('users', 'BaseUser') | ||
| + | </code> | ||
| + | |||
| + | ==== Choose a random element from DB ==== | ||
| + | <code> | ||
| + | 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() | ||
| + | </code> | ||
| + | |||
| + | ==== Clean migrations ==== | ||
| + | <code> | ||
| + | find . -path "*/migrations/*.py" -not -name "__init__.py" -delete | ||
| + | find . -path "*/migrations/*.pyc" -delete | ||
| + | </code> | ||
| + | |||
| + | === Script to reset the whole DB === | ||
| + | <code> | ||
| + | #!/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');" | ||
| </code> | </code> | ||