├── docs
├── .gitignore
├── after_view.png
├── db_column.png
├── db_table.png
├── sql_query.png
├── usertable.png
├── usertable2.png
├── before_view.png
├── sqluser_result1.png
├── sqluser_result2.png
├── sqluser_notquery.png
├── order_by_two.rst
├── initial_data.rst
├── singleton.rst
├── func_expressions.rst
├── numqueries.rst
├── f_query.rst
├── signals.rst
├── update_denormalized_fields.rst
├── order_by_related_model.rst
├── generic_models.rst
├── filefield.rst
├── duplicate.rst
├── subquery.rst
├── random.rst
├── self_fk.rst
├── existing_database.rst
├── Makefile
├── second_largest.rst
├── order_by_annotated_field.rst
├── column_name.rst
├── multiple_objects.rst
├── truncate.rst
├── uuid.rst
├── agregation.rst
├── keepdb.rst
├── refresh_from_db.rst
├── and_query.rst
├── copy.rst
├── or_query.rst
├── query_relatedtool.rst
├── select_some_fields.rst
├── case_insensitive.rst
├── table_name.rst
├── asc_or_desc.rst
├── distinct.rst
├── query.rst
├── notequal_query.rst
├── datetime.rst
├── null_vs_blank.rst
├── slugfield.rst
├── union.rst
├── join.rst
├── one_to_one.rst
├── database_view.rst
├── one_to_many.rst
├── index.rst
├── many_to_many.rst
├── multiple_databases.rst
└── conf.py
├── heroes_and_monsters
├── events
│ ├── __init__.py
│ ├── migrations
│ │ ├── __init__.py
│ │ ├── 0002_auto_20180228_1413.py
│ │ ├── 0006_article_slug.py
│ │ ├── 0003_userparent.py
│ │ ├── 0004_article.py
│ │ ├── 0005_columnname_tempuser.py
│ │ └── 0001_initial.py
│ ├── views.py
│ ├── apps.py
│ ├── tests.py
│ ├── admin.py
│ └── models.py
├── entities
│ ├── __init__.py
│ ├── migrations
│ │ ├── __init__.py
│ │ ├── 0002_auto_20180221_1830.py
│ │ └── 0001_initial.py
│ ├── tests.py
│ ├── views.py
│ ├── apps.py
│ ├── admin.py
│ └── models.py
├── heroes_and_monsters
│ ├── __init__.py
│ ├── wsgi.py
│ ├── urls.py
│ └── settings.py
├── .gitignore
├── requirements.txt
├── static
│ └── umsra_logo.png
├── templates
│ ├── entities
│ │ ├── heroes_changelist.html
│ │ └── villain_changeform.html
│ └── admin
│ │ ├── csv_form.html
│ │ └── base_site.html
└── manage.py
├── LICENSE
└── README.md
/docs/.gitignore:
--------------------------------------------------------------------------------
1 | _build/
2 |
--------------------------------------------------------------------------------
/heroes_and_monsters/events/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/heroes_and_monsters/entities/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/heroes_and_monsters/entities/migrations/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/heroes_and_monsters/events/migrations/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/heroes_and_monsters/heroes_and_monsters/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/heroes_and_monsters/.gitignore:
--------------------------------------------------------------------------------
1 | db.sqlite3
2 | *.pyc
3 | __pycache__
4 |
--------------------------------------------------------------------------------
/heroes_and_monsters/requirements.txt:
--------------------------------------------------------------------------------
1 | django==2.0.1
2 | Pillow
3 | django_extensions
--------------------------------------------------------------------------------
/docs/after_view.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/peterbe/django-orm-cookbook/master/docs/after_view.png
--------------------------------------------------------------------------------
/docs/db_column.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/peterbe/django-orm-cookbook/master/docs/db_column.png
--------------------------------------------------------------------------------
/docs/db_table.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/peterbe/django-orm-cookbook/master/docs/db_table.png
--------------------------------------------------------------------------------
/docs/sql_query.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/peterbe/django-orm-cookbook/master/docs/sql_query.png
--------------------------------------------------------------------------------
/docs/usertable.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/peterbe/django-orm-cookbook/master/docs/usertable.png
--------------------------------------------------------------------------------
/docs/usertable2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/peterbe/django-orm-cookbook/master/docs/usertable2.png
--------------------------------------------------------------------------------
/docs/before_view.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/peterbe/django-orm-cookbook/master/docs/before_view.png
--------------------------------------------------------------------------------
/docs/sqluser_result1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/peterbe/django-orm-cookbook/master/docs/sqluser_result1.png
--------------------------------------------------------------------------------
/docs/sqluser_result2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/peterbe/django-orm-cookbook/master/docs/sqluser_result2.png
--------------------------------------------------------------------------------
/heroes_and_monsters/entities/tests.py:
--------------------------------------------------------------------------------
1 | from django.test import TestCase
2 |
3 | # Create your tests here.
4 |
--------------------------------------------------------------------------------
/heroes_and_monsters/entities/views.py:
--------------------------------------------------------------------------------
1 | from django.shortcuts import render
2 |
3 | # Create your views here.
4 |
--------------------------------------------------------------------------------
/heroes_and_monsters/events/views.py:
--------------------------------------------------------------------------------
1 | from django.shortcuts import render
2 |
3 | # Create your views here.
4 |
--------------------------------------------------------------------------------
/docs/sqluser_notquery.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/peterbe/django-orm-cookbook/master/docs/sqluser_notquery.png
--------------------------------------------------------------------------------
/docs/order_by_two.rst:
--------------------------------------------------------------------------------
1 | How to order on two fields
2 | ========================================================================
3 |
--------------------------------------------------------------------------------
/heroes_and_monsters/events/apps.py:
--------------------------------------------------------------------------------
1 | from django.apps import AppConfig
2 |
3 |
4 | class EventsConfig(AppConfig):
5 | name = 'events'
6 |
--------------------------------------------------------------------------------
/docs/initial_data.rst:
--------------------------------------------------------------------------------
1 | How to provide initial/test data to tests?
2 | ========================================================================
3 |
--------------------------------------------------------------------------------
/heroes_and_monsters/entities/apps.py:
--------------------------------------------------------------------------------
1 | from django.apps import AppConfig
2 |
3 |
4 | class EntitiesConfig(AppConfig):
5 | name = 'entities'
6 |
--------------------------------------------------------------------------------
/heroes_and_monsters/static/umsra_logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/peterbe/django-orm-cookbook/master/heroes_and_monsters/static/umsra_logo.png
--------------------------------------------------------------------------------
/docs/singleton.rst:
--------------------------------------------------------------------------------
1 | How to ensure that only one object can be created?
2 | ========================================================================
3 |
--------------------------------------------------------------------------------
/docs/func_expressions.rst:
--------------------------------------------------------------------------------
1 | How to use arbitrary database functions in querysets?
2 | ========================================================================
3 |
--------------------------------------------------------------------------------
/docs/numqueries.rst:
--------------------------------------------------------------------------------
1 | How to assert that a function used a fixed number of queries?
2 | ========================================================================
3 |
--------------------------------------------------------------------------------
/docs/f_query.rst:
--------------------------------------------------------------------------------
1 | How to filter a queryset with criteria based on their field values
2 | ========================================================================
3 |
--------------------------------------------------------------------------------
/docs/signals.rst:
--------------------------------------------------------------------------------
1 | What signals are raised by Django during object creation or updation?
2 | ========================================================================
3 |
--------------------------------------------------------------------------------
/docs/update_denormalized_fields.rst:
--------------------------------------------------------------------------------
1 | How to update denormalized fields in other models on save?
2 | ========================================================================
3 |
--------------------------------------------------------------------------------
/docs/order_by_related_model.rst:
--------------------------------------------------------------------------------
1 | How to order on a field from a related model (with a foreign key)?
2 | ========================================================================
3 |
--------------------------------------------------------------------------------
/docs/generic_models.rst:
--------------------------------------------------------------------------------
1 | How to model which can be related to any kind of entity? (Eg. a Tag or a Comment?)
2 | ==============================================================================================
3 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | This work is licensed under a CC-BY-SA 4.0 (Creative Commons Attribution-ShareAlike 4.0 International License) licence.
2 | The full text is available at: https://creativecommons.org/licenses/by-sa/4.0/
3 |
--------------------------------------------------------------------------------
/heroes_and_monsters/templates/entities/heroes_changelist.html:
--------------------------------------------------------------------------------
1 | {% extends 'admin/change_list.html' %}
2 |
3 |
4 | {% block object-tools %}
5 | Import CSV
6 |
7 | {{ block.super }}
8 |
9 |
10 |
11 | {% endblock %}
12 |
--------------------------------------------------------------------------------
/heroes_and_monsters/templates/entities/villain_changeform.html:
--------------------------------------------------------------------------------
1 | {% extends 'admin/change_form.html' %}
2 |
3 | {% block submit_buttons_bottom %}
4 | {{ block.super }}
5 |
6 |
7 |
8 | {% endblock %}
9 |
--------------------------------------------------------------------------------
/heroes_and_monsters/templates/admin/csv_form.html:
--------------------------------------------------------------------------------
1 | {% extends 'admin/base.html' %}
2 |
3 | {% block content %}
4 |
5 |
11 |
12 |
13 |
14 | {% endblock %}
15 |
--------------------------------------------------------------------------------
/heroes_and_monsters/templates/admin/base_site.html:
--------------------------------------------------------------------------------
1 | {% extends "admin/base.html" %}
2 |
3 | {% load staticfiles %}
4 |
5 | {% block title %}{{ title }} | {{ site_title|default:_('Django site admin') }}{% endblock %}
6 |
7 | {% block branding %}
8 |
13 | {% endblock %}
14 |
15 | {% block nav-global %}{% endblock %}
16 |
--------------------------------------------------------------------------------
/heroes_and_monsters/heroes_and_monsters/wsgi.py:
--------------------------------------------------------------------------------
1 | """
2 | WSGI config for heroes_and_monsters project.
3 |
4 | It exposes the WSGI callable as a module-level variable named ``application``.
5 |
6 | For more information on this file, see
7 | https://docs.djangoproject.com/en/2.0/howto/deployment/wsgi/
8 | """
9 |
10 | import os
11 |
12 | from django.core.wsgi import get_wsgi_application
13 |
14 | os.environ.setdefault("DJANGO_SETTINGS_MODULE", "heroes_and_monsters.settings")
15 |
16 | application = get_wsgi_application()
17 |
--------------------------------------------------------------------------------
/docs/filefield.rst:
--------------------------------------------------------------------------------
1 | How to filter FileField without any file?
2 | ++++++++++++++++++++++++++++++++++++++++++++++
3 |
4 | Any :code:`FileField` or :code:`ImageField` mostly stores the path of the image wherever they are stored. So at sometimes when images/files are not stored the :code:`Field` will be left blank as a empty string. So to query FileField without any file we can query as under. ::
5 |
6 | no_files_objects = MyModel.objects.filter(file='') // This query will return all the objects of the model which don't have file stored in them.
--------------------------------------------------------------------------------
/heroes_and_monsters/events/migrations/0002_auto_20180228_1413.py:
--------------------------------------------------------------------------------
1 | # Generated by Django 2.0.1 on 2018-02-28 14:13
2 |
3 | from django.db import migrations, models
4 | import uuid
5 |
6 |
7 | class Migration(migrations.Migration):
8 |
9 | dependencies = [
10 | ('events', '0001_initial'),
11 | ]
12 |
13 | operations = [
14 | migrations.AlterField(
15 | model_name='event',
16 | name='id',
17 | field=models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False),
18 | ),
19 | ]
20 |
--------------------------------------------------------------------------------
/docs/duplicate.rst:
--------------------------------------------------------------------------------
1 | Find rows which have duplicate field values
2 | ==============================================
3 |
4 | .. image:: usertable2.png
5 |
6 | We can find duplicate records from the query as under.::
7 |
8 | >>> duplicates = User.objects.values('first_name').annotate(Count('id')).order_by().filter(id__count__gt=1)
9 | >>> duplicates
10 |
11 | >>> records = User.objects.filter(first_name__in=[item['first_name'] for item in duplicates])
12 | >>> print([item.id for item in records])
13 | [2, 11, 13]
--------------------------------------------------------------------------------
/heroes_and_monsters/events/migrations/0006_article_slug.py:
--------------------------------------------------------------------------------
1 | # Generated by Django 2.0.1 on 2018-03-08 13:50
2 |
3 | from django.db import migrations, models
4 | import django.utils.timezone
5 |
6 |
7 | class Migration(migrations.Migration):
8 |
9 | dependencies = [
10 | ('events', '0005_columnname_tempuser'),
11 | ]
12 |
13 | operations = [
14 | migrations.AddField(
15 | model_name='article',
16 | name='slug',
17 | field=models.SlugField(default=django.utils.timezone.now),
18 | preserve_default=False,
19 | ),
20 | ]
21 |
--------------------------------------------------------------------------------
/docs/subquery.rst:
--------------------------------------------------------------------------------
1 | How to do a subquery experession in Django?
2 | =============================================
3 |
4 | Subquery expression which is included in :code:`Django` from version :code:`1.11`. Lets talk about this with an example. We have a UserParent table which has OnetoOne relation with aut user. We will find all the users having their parents detail saved.
5 |
6 | >>> users = User.objects.all()
7 | >>> UserParent.objects.filter(user_id__in=Subquery(users.values('id')))
8 | , , ]>
9 |
--------------------------------------------------------------------------------
/heroes_and_monsters/manage.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | import os
3 | import sys
4 |
5 | if __name__ == "__main__":
6 | os.environ.setdefault("DJANGO_SETTINGS_MODULE", "heroes_and_monsters.settings")
7 | try:
8 | from django.core.management import execute_from_command_line
9 | except ImportError as exc:
10 | raise ImportError(
11 | "Couldn't import Django. Are you sure it's installed and "
12 | "available on your PYTHONPATH environment variable? Did you "
13 | "forget to activate a virtual environment?"
14 | )
15 | execute_from_command_line(sys.argv)
16 |
--------------------------------------------------------------------------------
/docs/random.rst:
--------------------------------------------------------------------------------
1 | How to select a random object from a model?
2 | ========================================================================
3 |
4 | For getting a random record from Django's model. We can order_by randomly and fetch the first record.
5 | Example ::
6 |
7 | >>> random_article = Article.objects.order_by('?').first()
8 | >>> random_article.headline
9 | 'Prime time'
10 | >>> random_article = Article.objects.order_by('?').first()
11 | >>> random_article.headline
12 | 'Morning news'
13 |
14 | Note: :code:`order_by('?')` queries may be expensive and slow, depending on the database backend you’re using.
15 |
--------------------------------------------------------------------------------
/docs/self_fk.rst:
--------------------------------------------------------------------------------
1 | How to include a self-referencing Foreignkey in a model
2 | ========================================================================
3 |
4 | Self-referencing fk(recursive relationship) works similar to what we do for One to Many relationships. But as the name suggests, the model references itself. Self reference Foreignkey can be achived in two ways: ::
5 |
6 | class Parent(models.Model):
7 | parent_ref = models.ForeignKey('self', on_delete=models.CASCADE))
8 |
9 | // OR
10 |
11 | class Parent(models.Model):
12 | parent_ref = models.ForeignKey("Parent", on_delete=models.CASCADE))
13 |
14 |
--------------------------------------------------------------------------------
/docs/existing_database.rst:
--------------------------------------------------------------------------------
1 | How to convert existing databases to Django models?
2 | =====================================================
3 |
4 | Django comes with a utility called inspectdb that can create models by introspecting an existing database. You can view the output by running this command ::
5 |
6 | $ python manage.py inspectdb
7 |
8 | Befor running this you will have to configure youre database in the :code: `settings.py` file. The returned result will be a file having all model related stuff. You may want to save that file ::
9 |
10 | $ python manage.py inspectdb > models.py
11 |
12 | The output file will be saved to your current directory.
13 |
--------------------------------------------------------------------------------
/heroes_and_monsters/heroes_and_monsters/urls.py:
--------------------------------------------------------------------------------
1 | from django.contrib import admin
2 | from django.urls import path
3 | from django.conf import settings
4 | from django.conf.urls.static import static
5 |
6 | admin.site.site_header = "UMSRA Admin"
7 | admin.site.site_title = "UMSRA Admin Portal"
8 | admin.site.index_title = "Welcome to UMSRA Researcher Portal"
9 |
10 | from events.admin import event_admin_site
11 |
12 |
13 | urlpatterns = [
14 | path('entity-admin/', admin.site.urls),
15 | path('event-admin/', event_admin_site.urls),
16 | ]
17 |
18 | if settings.DEBUG is True:
19 | urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
20 |
--------------------------------------------------------------------------------
/docs/Makefile:
--------------------------------------------------------------------------------
1 | # Minimal makefile for Sphinx documentation
2 | #
3 |
4 | # You can set these variables from the command line.
5 | SPHINXOPTS =
6 | SPHINXBUILD = sphinx-build
7 | SPHINXPROJ = DjangoORMCookbook
8 | SOURCEDIR = .
9 | BUILDDIR = _build
10 |
11 | # Put it first so that "make" without argument is like "make help".
12 | help:
13 | @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
14 |
15 | .PHONY: help Makefile
16 |
17 | # Catch-all target: route all unknown targets to Sphinx using the new
18 | # "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
19 | %: Makefile
20 | @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
--------------------------------------------------------------------------------
/heroes_and_monsters/events/tests.py:
--------------------------------------------------------------------------------
1 | from django.test import TestCase
2 | from .models import User
3 |
4 | # Create your tests here.
5 | class TestORM(TestCase):
6 | def test_update_result(self):
7 | userobject = User.objects.create(username='testuser', first_name='Test', last_name='user')
8 | User.objects.filter(username='testuser').update(username='test1user')
9 | # At this point userobject.val is still testuser, but the value in the database
10 | # was updated to test1user. The object's updated value needs to be reloaded
11 | # from the database.
12 | userobject.refresh_from_db()
13 | self.assertEqual(userobject.username, 'test1user')
14 |
--------------------------------------------------------------------------------
/docs/second_largest.rst:
--------------------------------------------------------------------------------
1 | How to find second largest record using Django ORM ?
2 | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
3 |
4 | We have come across situations when we want to query second highest user depending on his age or salary. Though ORM gives as the flexibility of finding first(), last() item from the queryset but not nth item.
5 |
6 | .. image:: usertable.png
7 |
8 | We can find Nth records from the query by using slice operator.
9 |
10 | >>> u = User.objects.order_by('-id')[1] // Second Highest record w.r.t 'id'
11 | >>> u.first_name
12 | 'Raghu'
13 | >>> u = User.objects.order_by('-id')[2] // Third Highest record w.r.t 'id'
14 | >>> u.first_name
15 | 'Sohan'
16 |
--------------------------------------------------------------------------------
/docs/order_by_annotated_field.rst:
--------------------------------------------------------------------------------
1 | How to order on an annotated field?
2 | ==========================================
3 |
4 | Here we will talk about two models i.e., :code:`Article` and :code:`User`. Article has FK relationship with User model. Here we will be counting the articles created by user and order them in ascending order. ::
5 |
6 |
7 | >>> from django.db.models import Sum
8 | >>> Article.objects.values('reporter__username').annotate(reporter_article = Sum('reporter')).order_by('reporter_article')
9 |
--------------------------------------------------------------------------------
/docs/column_name.rst:
--------------------------------------------------------------------------------
1 | How to specify the column name for model field?
2 | =====================================================
3 |
4 | Naming of a column in the model can be achieved py passing a :code:`db_column` parameter with some name. If we don't pass this parameter django creates a column with the field name which we give. ::
5 |
6 | class ColumnName(models.Model):
7 | a = models.CharField(max_length=40,db_column='column1')
8 | column2 = models.CharField(max_length=50)
9 |
10 | def __str__(self):
11 | return self.a
12 |
13 | .. image:: db_column.png
14 |
15 | Above we can :code:`db_coloumn` has higher priority over :code:`field name`. First column is named as column1 but not as a.
16 |
--------------------------------------------------------------------------------
/docs/multiple_objects.rst:
--------------------------------------------------------------------------------
1 | How to create multiple objects in one shot?
2 | ++++++++++++++++++++++++++++++++++++++++++++++++++
3 |
4 | There are conditions when we want to save multiple objects in one go. Say we want to add multiple categories at once and we don't want to make many queries to the database.
5 | We can use django-ORM's builtin method bulk_create for creating multiple objects at one shot.
6 |
7 | Code ::
8 |
9 | >>> Category.objects.all().count()
10 | 2
11 | >>> Category.objects.bulk_create([Category(name="Foods Items"), Category(name="Fruits"), Category(name="Vegetables")])
12 | [, , ]
13 | >>> Category.objects.all().count()
14 | 5
15 |
--------------------------------------------------------------------------------
/docs/truncate.rst:
--------------------------------------------------------------------------------
1 | How to perform truncate like operation using Django ORM?
2 | ==========================================================
3 |
4 | Truncate statement in SQL is mainly meant to deallocate a table, i.e., empty a table for future use.
5 | Though django doesn't provide any such operation https://code.djangoproject.com/ticket/16427, but still similar result can be achived using :code:`delete()` method.
6 | For example:
7 |
8 | >>> Article.objects.all().count()
9 | 7
10 | >>> Article.objects.all().delete()
11 | (7, {'events.Article': 7})
12 | >>> Article.objects.all().count()
13 | 0
14 |
15 | From above example it is clear that Article model has no data in it. Which was expected from Truncate statement.
--------------------------------------------------------------------------------
/docs/uuid.rst:
--------------------------------------------------------------------------------
1 | How to use a UUID instead of ID as prmary key?
2 | ++++++++++++++++++++++++++++++++++++++++++++++++++
3 |
4 | Whenever we create any new model, there is an ID field attached to it. The ID field's data type will be Integer by default.
5 |
6 | To make id field as UUID, there is a new field type UUIDField which was added in django version 1.8+.
7 |
8 | Example ::
9 |
10 | import uuid
11 | from django.db import models
12 |
13 | class Event(models.Model):
14 | id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
15 | details = models.TextField()
16 | years_ago = models.PositiveIntegerField()
17 |
18 | >>> eventobject = Event.objects.all()
19 | >>> eventobject.first().id
20 | '3cd2b4b0c36f43488a93b3bb72029f46'
--------------------------------------------------------------------------------
/docs/agregation.rst:
--------------------------------------------------------------------------------
1 | How to group records in Django ORM?
2 | ========================================
3 |
4 | Grouping of records in Django ORM can be done using aggregation functions like :code:`Max`, :code:`Min`, :code:`Avg`, :code:`Sum`. Django queries help to create, retrieve, update and delete objects. But sometimes we need to get aggregated values from the objects. We can get them by example shown below ::
5 |
6 | >>> from django.db.models import Avg, Max, Min, Sum, Count
7 | >>> User.objects.all().aggregate(Avg('id'))
8 | {'id__avg': 7.571428571428571}
9 | >>> User.objects.all().aggregate(Max('id'))
10 | {'id__max': 15}
11 | >>> User.objects.all().aggregate(Min('id'))
12 | {'id__min': 1}
13 | >>> User.objects.all().aggregate(Sum('id'))
14 | {'id__sum': 106}
15 |
--------------------------------------------------------------------------------
/docs/keepdb.rst:
--------------------------------------------------------------------------------
1 | How to speed tests by reusing database between test runs?
2 | ================================================================
3 |
4 | Whenever we execute the command :code:`python manage.py test` new db is created everytime. This won't effect if we have less migrations to execute or db size is small.
5 | But when we have many migrations,it takes long time to run the test cases. So to avoid such situations we may keep the old database for our use.
6 | You can prevent the test databases from being destroyed by adding the :code:`--keepdb` flag to the test command. This will preserve the test database between runs. If the database does not exist, it will first be created.
7 | Any migrations will also be applied in order to keep it up to date. ::
8 |
9 | $ python manage.py test --keepdb
10 |
11 |
--------------------------------------------------------------------------------
/docs/refresh_from_db.rst:
--------------------------------------------------------------------------------
1 | How to reload a model object from the database?
2 | ========================================================================
3 |
4 | Models can be reloaded from the databse using :code:`refresh_from_db()` method. THis proves helpful during testing. For example. ::
5 |
6 | class TestORM(TestCase):
7 | def test_update_result(self):
8 | userobject = User.objects.create(username='testuser', first_name='Test', last_name='user')
9 | User.objects.filter(username='testuser').update(username='test1user')
10 | # At this point userobject.val is still testuser, but the value in the database
11 | # was updated to test1user. The object's updated value needs to be reloaded
12 | # from the database.
13 | userobject.refresh_from_db()
14 | self.assertEqual(userobject.username, 'test1user')
--------------------------------------------------------------------------------
/docs/and_query.rst:
--------------------------------------------------------------------------------
1 | How to do AND queries in Django ORM?
2 | ++++++++++++++++++++++++++++++++++++++++++++++++++
3 |
4 | .. image:: usertable.png
5 |
6 | Let's say we have a table called auth_user having fields as username, first_name, last_name, email etc.., and we want to perform OR operation on it with firstname starting with 'R' AND'ing last_name starting with 'D'.
7 |
8 | Our SQL query for the above condition will look somethng like ::
9 |
10 | SELECT username, first_name, last_name, email FROM auth_user WHERE first_name LIKE 'R%' AND last_name LIKE 'D%';
11 |
12 | .. image:: sqluser_result2.png
13 |
14 | Similarly our ORM query looks like ::
15 |
16 | queryset = User.objects.filter(first_name__startswith='R') & User.objects.filter(last_name__startswith='D')
17 | queryset
18 | , , ]>
19 |
--------------------------------------------------------------------------------
/docs/copy.rst:
--------------------------------------------------------------------------------
1 | How to copy or clone an existing model object?
2 | ========================================================================
3 |
4 | There is no built-in method for copying model instances, it is possible to easily create new instance with all fields’ values copied. That instance can be saved again by setting instance's :code:`pk` to :code:`None`. For example ::
5 |
6 | >>> Article.objects.all().count()
7 | 5
8 | >>> reporter = User.objects.get(id = 1)
9 | >>> reporter
10 |
11 | >>> article = Article(headline="Article to test copying instance", pub_date=date(2018, 3, 11), reporter=reporter)
12 | >>> article.pk
13 | 7
14 | >>> article.pk = None // Assigning None to pk, to make a copy of an instance.
15 | >>> article.save()
16 | >>> article.pk
17 | 8
18 | >>> Article.objects.all().count()
19 | 7
20 |
--------------------------------------------------------------------------------
/docs/or_query.rst:
--------------------------------------------------------------------------------
1 | How to do OR queries in Django ORM?
2 | ++++++++++++++++++++++++++++++++++++++++++++++++++
3 |
4 | .. image:: usertable.png
5 |
6 | Let's say we have a table called auth_user having fields as username, first_name, last_name, email etc.., and we want to perform AND operation on it with firstname starting with 'R' OR'ing last_name starting with 'D'.
7 |
8 | Our SQL query for the above condition will look somethng like ::
9 |
10 | SELECT username, first_name, last_name, email FROM auth_user WHERE first_name LIKE 'R%' OR last_name LIKE 'D%';
11 |
12 | .. image:: sqluser_result1.png
13 |
14 | Similarly our ORM query looks like ::
15 |
16 | queryset = User.objects.filter(first_name__startswith='R') | User.objects.filter(last_name__startswith='D')
17 | queryset
18 | , , , , ]>
19 |
--------------------------------------------------------------------------------
/docs/query_relatedtool.rst:
--------------------------------------------------------------------------------
1 | How to solve problems using query related tools?
2 | ==================================================
3 |
4 | In our previous examples when we did OR'ing and AND'ing of the queries. Similar queries could be done using :code:`Query related tools` ::
5 |
6 | >>> from django.db.models import Q
7 | >>> queryset = User.objects.filter(Q(first_name__startswith='R') | Q(last_name__startswith='D')) // OR Operation
8 | >>> queryset
9 | , , , , ]>
10 | >>> queryset = User.objects.filter(Q(first_name__startswith='R') & Q(last_name__startswith='D')) // AND Operation
11 | >>> queryset
12 | , , ]>
13 |
14 | Some other query related tools apart from :code:`Q()` objects are :code:`select_related()` and :code:`prefetch_related()`.
15 |
--------------------------------------------------------------------------------
/docs/select_some_fields.rst:
--------------------------------------------------------------------------------
1 | How to select some fields only in a queryset?
2 | ++++++++++++++++++++++++++++++++++++++++++++++++++
3 |
4 | .. image:: usertable.png
5 |
6 | We have a auth_user model having some 5 fields in it. But sometimes we are not in need to use all the fields so for such situations we can query only desired fields.
7 | This can be achieved my ``values`` method.
8 |
9 | Say, we want to get firstname and lastname off all the users having initials as **R** ::
10 |
11 | >>> User.objects.filter(first_name__startswith='R').values('first_name', 'last_name')
12 | >> User.objects.all().order_by('username').values_list('username', flat=True)
8 |
9 |
10 | If we want to order queryset in case insensitive manner, we can do like this . ::
11 |
12 | >>> from django.db.models.functions import Lower
13 | >>> User.objects.all().order_by(Lower('username')).values_list('username', flat=True)
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/docs/table_name.rst:
--------------------------------------------------------------------------------
1 | How to specify the table name for a model?
2 | ===============================================
3 |
4 |
5 | To save you time, Django automatically derives the name of the database table from the name of your model class and the app that contains it.
6 | A model’s database table name is constructed by joining the model’s “app label” – the name you used in manage.py startapp – to the model’s class name,
7 | with an underscore between them.
8 |
9 | We have two apps in our demo application i.e., :code:`entities` and :code:`events` so all the models in them will have app names as the prefixes followed by `_` then the model name.
10 |
11 | .. image:: db_table.png
12 |
13 | For renaming them we cab use :code:`db_table` parameter ::
14 |
15 | class TempUser(models.Model):
16 | first_name = models.CharField(max_length=100)
17 | . . .
18 | class Meta:
19 | db_table = "temp_user"
--------------------------------------------------------------------------------
/docs/asc_or_desc.rst:
--------------------------------------------------------------------------------
1 | How to order a queryset in ascending or descending order?
2 | =============================================================
3 |
4 | Ordering of the queryset can be achieved by order_by method. We need to pass the field on whose basis we need to Order (ascending/descending) the result.
5 | Query looks like this ::
6 |
7 | >>> User.objects.all().order_by('date_joined') // For ascending
8 | , , , , , , , , , , , , ]>
9 | >>> User.objects.all().order_by('-date_joined') // For descending; Not '-' sign in order_by method
10 | , , , , , , , , , , , , ]>
11 |
--------------------------------------------------------------------------------
/docs/distinct.rst:
--------------------------------------------------------------------------------
1 | How to find distinct field values from queryset?
2 | ========================================================================
3 |
4 | .. image:: usertable2.png
5 |
6 | We can find distinct records from the query as under.::
7 |
8 | >>> distinct = User.objects.values('first_name').annotate(Count('id')).order_by().filter(id__count=1)
9 | >>> distinct
10 |
11 | >>> records = User.objects.filter(first_name__in=[item['first_name'] for item in distinct])
12 | >>> print([item.id for item in records])
13 | [1, 3, 4, 5, 6, 7, 8, 9, 10, 12]
--------------------------------------------------------------------------------
/docs/query.rst:
--------------------------------------------------------------------------------
1 | How to find the query associated with a queryset?
2 | ++++++++++++++++++++++++++++++++++++++++++++++++++
3 |
4 | We have been working with Django ORM from long time, but deep inside us sometimes comes a thought how is django ORM making our queries execute or what is the SQL of the code which we are writing.
5 |
6 | We have a model called events for querying it with django we will write something like ::
7 |
8 | >>> queryset = events.objects.all()
9 | >>> print(queryset.query)
10 | SELECT "events_event"."id", "events_event"."epic_id", "events_event"."details", "events_event"."years_ago" FROM "events_event"
11 |
12 | .. image:: sql_query.png
13 |
14 | Example 2 ::
15 |
16 | >>> queryset = Event.objects.filter(id=1, years_ago__gt=5)
17 | >>> print(queryset.query)
18 | SELECT "events_event"."id", "events_event"."epic_id", "events_event"."details", "events_event"."years_ago" FROM "events_event" WHERE ("events_event"."years_ago" > 5 AND "events_event"."id" = 1)
19 |
20 |
--------------------------------------------------------------------------------
/docs/notequal_query.rst:
--------------------------------------------------------------------------------
1 | How to do NOT EQUAL query in Django queryset?
2 | ++++++++++++++++++++++++++++++++++++++++++++++++++
3 |
4 | .. image:: usertable.png
5 |
6 | Let's say we have a table called auth_user having fields as username, first_name, last_name, email etc.., and we want to perform NOT operation for fetching users with id NOT < 5.
7 |
8 | Our SQL query for the above condition will look somethng like ::
9 |
10 | SELECT id, username, first_name, last_name, email FROM auth_user WHERE NOT id < 5;
11 |
12 | .. image:: sqluser_notquery.png
13 |
14 | Way 1 using exclude ::
15 |
16 | >>> queryset = User.objects.exclude(id__lt=5)
17 | >>> queryset
18 | , , , , , ]>
19 |
20 | Way 2 using Q() method aka query tools ::
21 |
22 | >>> from django.db.models import Q
23 | >>> queryset = User.objects.filter(~Q(id__lt=5))
24 | >>> queryst
25 | , , , , , ]>
26 |
27 |
--------------------------------------------------------------------------------
/heroes_and_monsters/entities/admin.py:
--------------------------------------------------------------------------------
1 | from django.contrib import admin
2 | from .models import Hero, Villain, Category, Origin, HeroProxy, AllEntity, HeroAcquaintance
3 |
4 | @admin.register(Hero)
5 | class HeroAdmin(admin.ModelAdmin):
6 | # form = HeroForm
7 |
8 | list_display = ("name", "is_immortal", "category", "origin")
9 | list_filter = ("is_immortal", "category", "origin")
10 |
11 | @admin.register(HeroProxy)
12 | class HeroProxyAdmin(admin.ModelAdmin):
13 | list_display = ("name", "is_immortal", "category", "origin",)
14 | readonly_fields = ("name", "is_immortal", "category", "origin",)
15 |
16 | @admin.register(Villain)
17 | class VillainAdmin(admin.ModelAdmin):
18 | list_display = ("name", "category", "origin")
19 |
20 | class VillainInline(admin.StackedInline):
21 | model = Villain
22 |
23 | @admin.register(Category)
24 | class CategoryAdmin(admin.ModelAdmin):
25 | list_display = ("name",)
26 |
27 | inlines = [VillainInline]
28 |
29 | @admin.register(Origin)
30 | class OriginAdmin(admin.ModelAdmin):
31 | list_display = ("name",)
32 |
--------------------------------------------------------------------------------
/heroes_and_monsters/events/migrations/0004_article.py:
--------------------------------------------------------------------------------
1 | # Generated by Django 2.0.1 on 2018-03-07 07:25
2 |
3 | from django.conf import settings
4 | from django.db import migrations, models
5 | import django.db.models.deletion
6 |
7 |
8 | class Migration(migrations.Migration):
9 |
10 | dependencies = [
11 | migrations.swappable_dependency(settings.AUTH_USER_MODEL),
12 | ('events', '0003_userparent'),
13 | ]
14 |
15 | operations = [
16 | migrations.CreateModel(
17 | name='Article',
18 | fields=[
19 | ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
20 | ('headline', models.CharField(max_length=100)),
21 | ('pub_date', models.DateField()),
22 | ('reporter', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='reporter', to=settings.AUTH_USER_MODEL)),
23 | ],
24 | options={
25 | 'ordering': ('headline',),
26 | },
27 | ),
28 | ]
29 |
--------------------------------------------------------------------------------
/docs/datetime.rst:
--------------------------------------------------------------------------------
1 | How to convert string to datetime and store in database?
2 | ============================================================
3 |
4 | We can convert a date-string and store it in the database using django in many ways. Few of them are discussed below.
5 | Lets say we have a date-string as "2018-03-11" we can not directly store it to our date field, so we can use some dateparser or python library for it. ::
6 |
7 | >>> user = User.objects.get(id=1)
8 | >>> date_str = "2018-03-11"
9 | >>> from django.utils.dateparse import parse_date // Way 1
10 | >>> temp_date = parse_date(date_str)
11 | >>> a1 = Article(headline="String converted to date", pub_date=temp_date, reporter=user)
12 | >>> a1.save()
13 | >>> a1.pub_date
14 | datetime.date(2018, 3, 11)
15 | >>> from datetime import datetime // Way 2
16 | >>> temp_date = datetime.strptime(date_str, "%Y-%m-%d").date()
17 | >>> a2 = Article(headline="String converted to date way 2", pub_date=temp_date, reporter=user)
18 | >>> a2.save()
19 | >>> a2.pub_date
20 | datetime.date(2018, 3, 11)
21 |
22 |
23 |
--------------------------------------------------------------------------------
/heroes_and_monsters/events/migrations/0005_columnname_tempuser.py:
--------------------------------------------------------------------------------
1 | # Generated by Django 2.0.1 on 2018-03-08 06:09
2 |
3 | from django.db import migrations, models
4 |
5 |
6 | class Migration(migrations.Migration):
7 |
8 | dependencies = [
9 | ('events', '0004_article'),
10 | ]
11 |
12 | operations = [
13 | migrations.CreateModel(
14 | name='TempUser',
15 | fields=[
16 | ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
17 | ('first_name', models.CharField(max_length=100)),
18 | ],
19 | options={
20 | 'managed': False,
21 | 'db_table': 'temp_user',
22 | },
23 | ),
24 | migrations.CreateModel(
25 | name='ColumnName',
26 | fields=[
27 | ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
28 | ('a', models.CharField(db_column='column1', max_length=40)),
29 | ('column2', models.CharField(max_length=50)),
30 | ],
31 | ),
32 | ]
33 |
--------------------------------------------------------------------------------
/docs/null_vs_blank.rst:
--------------------------------------------------------------------------------
1 | What is the difference between :code:`null=True` and :code:`blank=True`?
2 | ===============================================================================
3 |
4 | The default value of both :code:`null` and :code:`blank` is :code:`False`. Both of these values work at field level i.e., whether we want to keep a field null or blank.
5 |
6 | :code:`null=True` will set the field's value to NULL i.e., no data. It is basically for the databases column value. ::
7 |
8 | date = models.DateTimeField(null=True)
9 |
10 | :code:`blank=True` determines whether the field will be required in forms. This includes the admin and your own custom forms. ::
11 |
12 | title = models.CharField(blank=True) // title can be kept blank. In the database ("") will be stored.
13 |
14 | :code:`null=True` :code:`blank=True` This means that the field is optional in all circumstances. ::
15 |
16 | epic = models.ForeignKey(null=True, blank=True)
17 | // The exception is CharFields() and TextFields(), which in Django are never saved as NULL. Blank values are stored in the DB as an empty string ('').
18 |
19 | Also there is a special case, when you need to accept NULL values for a :code:`BooleanField`, use :code:`NullBooleanField`.
--------------------------------------------------------------------------------
/docs/slugfield.rst:
--------------------------------------------------------------------------------
1 | How to use slug field with django for more readability?
2 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
3 |
4 | Slug is a part of a URL which identifies a particular page on a website in a form readable by users. For making it work django od=ffers us a slugfield. It can be implimented as under.
5 | We already had a model :code:`Article` we will be adding slugfield to it to make it user readable. ::
6 |
7 | from django.utils.text import slugify
8 | class Article(models.Model):
9 | headline = models.CharField(max_length=100)
10 | . . .
11 | slug = models.SlugField(unique=True)
12 |
13 | def save(self, *args, **kwargs):
14 | self.slug = slugify(self.headline)
15 | super(Article, self).save(*args, **kwargs)
16 | . . .
17 |
18 | >>> u1 = User.objects.get(id=1)
19 | >>> from datetime import date
20 | >>> a1 = Article.objects.create(headline="todays market report", pub_date=date(2018, 3, 6), reporter=u1)
21 | >>> a1.save()
22 | // slug here is auto-generated, we haven't created it in the above create method.
23 | >>> a1.slug
24 | 'todays-market-report'
25 |
26 | Slug is useful because:
27 | | it's human friendly (eg. /blog/ instead of /1/).
28 | | it's good SEO to create consistency in title, heading and URL.
--------------------------------------------------------------------------------
/docs/union.rst:
--------------------------------------------------------------------------------
1 | How to do union of two querysets from same model?
2 | ++++++++++++++++++++++++++++++++++++++++++++++++++++
3 |
4 | The UNION operator is used to combine the result-set of two or more querysets.
5 |
6 | Lets continue with our auth_user model and generate 2 querysets to perform union operation ::
7 |
8 | >>> q1 = User.objects.filter(id__gte=5)
9 | >>> q1
10 | , , , , , ]>
11 | >>> q2 = q2 = User.objects.filter(id__lte=9)
12 | >>> q2
13 | , , , , , , , , ]>
14 | >>> q1.union(q2)
15 | , , , , , , , , , ]>
16 | >>> q2.union(q1)
17 | , , , , , , , , , ]>
18 |
19 | What you should not do ::
20 |
21 | >>> q3 = EventVillain.objects.all()
22 | >>> q3
23 | ]>
24 | >>> q1.union(q3)
25 | django.db.utils.OperationalError: SELECTs to the left and right of UNION do not have the same number of result columns
26 |
27 |
28 | Note: The union operation can be performed only with the querysets having same fields and the datatypes. Hence our last union operation encountered error.
--------------------------------------------------------------------------------
/docs/join.rst:
--------------------------------------------------------------------------------
1 | How to perform join operations in django ORM?
2 | ======================================================
3 |
4 | A SQL Join statement is used to combine data or rows from two or more tables based on a common field between them. Join can be carried out in many ways. Some are shown below. ::
5 |
6 | >>> a1 = Article.objects.select_related('reporter') // Using select_related
7 | >>> a1
8 | , , , , , ]>
9 | >>> print(a1.query)
10 | SELECT "events_article"."id", "events_article"."headline", "events_article"."pub_date", "events_article"."reporter_id", "events_article"."slug", "auth_user"."id", "auth_user"."password", "auth_user"."last_login", "auth_user"."is_superuser", "auth_user"."username", "auth_user"."first_name", "auth_user"."last_name", "auth_user"."email", "auth_user"."is_staff", "auth_user"."is_active", "auth_user"."date_joined" FROM "events_article" INNER JOIN "auth_user" ON ("events_article"."reporter_id" = "auth_user"."id") ORDER BY "events_article"."headline" ASC
11 | >>> a2 = Article.objects.filter(reporter__username='John')
12 | >>> a2
13 | , , , , ]>
14 | >>> print(a2.query)
15 | SELECT "events_article"."id", "events_article"."headline", "events_article"."pub_date", "events_article"."reporter_id", "events_article"."slug" FROM "events_article" INNER JOIN "auth_user" ON ("events_article"."reporter_id" = "auth_user"."id") WHERE "auth_user"."username" = John ORDER BY "events_article"."headline" ASC
--------------------------------------------------------------------------------
/docs/one_to_one.rst:
--------------------------------------------------------------------------------
1 | How to model one to one relationships?
2 | ===============================================
3 |
4 | One-to-one relationships occur when there is exactly one record in the first table that corresponds to one record in the related table.
5 | Here we have an example where we know that each individual can have only one Biological parents i.e., Mother and Father.
6 | We already have auth user model with us, we will add a new model UserParent as described below. ::
7 |
8 | from django.contrib.auth.models import User
9 |
10 | class UserParent(models.Model):
11 | user = models.OneToOneField(
12 | User,
13 | on_delete=models.CASCADE,
14 | primary_key=True,
15 | )
16 | father_name = models.CharField(max_length=100)
17 | mother_name = models.CharField(max_length=100)
18 |
19 | >>> u1 = User.objects.get(first_name='Ritesh', last_name='Deshmukh')
20 | >>> u2 = User.objects.get(first_name='Sohan', last_name='Upadhyay')
21 | >>> p1 = UserParent(user=u1, father_name='Vilasrao Deshmukh', mother_name='Vaishali Deshmukh')
22 | >>> p1.save()
23 | >>> p1.user.first_name
24 | 'Ritesh'
25 | >>> p2 = UserParent(user=u2, father_name='Mr R S Upadhyay', mother_name='Mrs S K Upadhyay')
26 | >>> p2.save()
27 | >>> p2.user.last_name
28 | 'Upadhyay'
29 |
30 | The on_delete method is used to tell Django what to do with model instances that depend on the model instance you delete. (e.g. a ForeignKey relationship). The on_delete=models.CASCADE tells Django to cascade the deleting effect i.e. continue deleting the dependent models as well. ::
31 |
32 | >>> u2.delete()
33 |
34 | Will also delete the related record of UserParent.
35 |
--------------------------------------------------------------------------------
/heroes_and_monsters/events/admin.py:
--------------------------------------------------------------------------------
1 | from django.contrib import admin
2 | from django.contrib.auth.models import User, Group
3 |
4 |
5 | from django.contrib.admin import AdminSite
6 | from .models import Epic, Event, EventHero, EventVillain, Article
7 |
8 |
9 | class EventAdminSite(AdminSite):
10 | site_header = "UMSRA Events Admin2"
11 | site_title = "UMSRA Events Admin Portal"
12 | index_title = "Welcome to UMSRA Researcher Events Portal"
13 |
14 |
15 | def get_app_list(self, request):
16 | """
17 | Return a sorted list of all the installed apps that have been
18 | registered in this site.
19 | """
20 | ordering = {
21 | "Event heros": 1,
22 | "Event villains": 2,
23 | "Epics": 3,
24 | "Events": 4,
25 | "Articles": 5
26 | }
27 | app_dict = self._build_app_dict(request)
28 | # a.sort(key=lambda x: b.index(x[0]))
29 | # Sort the apps alphabetically.
30 | app_list = sorted(app_dict.values(), key=lambda x: x['name'].lower())
31 |
32 | # Sort the models alphabetically within each app.
33 | for app in app_list:
34 | app['models'].sort(key=lambda x: ordering[x['name']])
35 |
36 | return app_list
37 |
38 | event_admin_site = EventAdminSite(name='event_admin')
39 |
40 | class EventAdmin(admin.ModelAdmin):
41 | list_display = ('id', 'epic', 'years_ago')
42 | class Meta:
43 | model = Event
44 |
45 | class ArticleAdmin(admin.ModelAdmin):
46 | list_display = ('id', 'headline', 'slug')
47 | prepopulated_fields = {"slug": ("headline",)}
48 | class Meta:
49 | model = Article
50 |
51 |
52 | event_admin_site.register(Epic)
53 | event_admin_site.register(Event, EventAdmin)
54 | event_admin_site.register(EventHero)
55 | event_admin_site.register(EventVillain)
56 | event_admin_site.register(Article, ArticleAdmin)
--------------------------------------------------------------------------------
/docs/database_view.rst:
--------------------------------------------------------------------------------
1 | How to add a model for a database view?
2 | ===============================================
3 |
4 | A database view is a searchable object in a database that is defined by a query. Though a view doesn’t store data, some refer to a views as “virtual tables,” you can query a view like you can a table. A view can combine data from two or more table, using joins, and also just contain a subset of information. This makes them convenient to abstract, or hide, complicated queries.
5 |
6 | In our SqliteStuio we can see 26 tables and no views.
7 |
8 | .. image:: before_view.png
9 |
10 | Lets create a simple view. ::
11 |
12 | create view temp_user as
13 | select id, first_name from auth_user;
14 |
15 | After the view is created, we can see 26 tables and 1 view.
16 |
17 | .. image:: after_view.png
18 |
19 | We can create its related model in our app, by :code:`managed = False` and :code:`db_table="temp_user"` ::
20 |
21 | class TempUser(models.Model):
22 | first_name = models.CharField(max_length=100)
23 |
24 | class Meta:
25 | managed = False
26 | db_table = "temp_user"
27 |
28 | // We can query the newly created view similar to what we do for any table.
29 | >>> TempUser.objects.all().values()
30 |
31 | // You cannot insert new reord in a view.
32 | >>> TempUser.objects.create(first_name='Radhika', id=15)
33 | Traceback (most recent call last):
34 | ...
35 | django.db.utils.OperationalError: cannot modify temp_user because it is a view
36 |
37 | For view having union operation refer to :
38 | http://books.agiliq.com/projects/django-admin-cookbook/en/latest/database_view.html?highlight=view
39 |
--------------------------------------------------------------------------------
/docs/one_to_many.rst:
--------------------------------------------------------------------------------
1 | How to model one to many relationships?
2 | ===============================================
3 |
4 | In relational databases, a one-to-many relationship occurs when a parent record in one table can potentially reference several child records in another table. In a one-to-many relationship, the parent is not required to have child records; therefore, the one-to-many relationship allows zero child records, a single child record or multiple child records.
5 | To define a many-to-one relationship, use `ForeignKey`.::
6 |
7 | class Article(models.Model):
8 | headline = models.CharField(max_length=100)
9 | pub_date = models.DateField()
10 | reporter = models.ForeignKey(User, on_delete=models.CASCADE, related_name='reporter')
11 |
12 | def __str__(self):
13 | return self.headline
14 |
15 | class Meta:
16 | ordering = ('headline',)
17 |
18 | >>> u1 = User(username='johny1', first_name='Johny', last_name='Smith', email='johny@example.com')
19 | >>> u1.save()
20 | >>> u2 = User(username='alien', first_name='Alien', last_name='Mars', email='alien@example.com')
21 | >>> u2.save()
22 | >>> from datetime import date
23 | >>> a1 = Article(headline="This is a test", pub_date=date(2018, 3, 6), reporter=u1)
24 | >>> a1.save()
25 | >>> a1.reporter.id
26 | 13
27 | >>> a1.reporter
28 |
29 |
30 | If you try to assign an object before saving it you will encounter a ValueError ::
31 |
32 | >>> u3 = User(username='someuser', first_name='Some', last_name='User', email='some@example.com')
33 | >>> Article.objects.create(headline="This is a test", pub_date=date(2018, 3, 7), reporter=u1)
34 | Traceback (most recent call last):
35 | ...
36 | ValueError: save() prohibited to prevent data loss due to unsaved related object 'reporter'.
37 | >>> Article.objects.create(headline="This is a test", pub_date=date(2018, 3, 7), reporter=u1)
38 | >>> Article.objects.filter(reporter=u1)
39 | , ]>
40 |
41 | The above queryset shows User u1 with multiple Articles. Hence One to Many.
--------------------------------------------------------------------------------
/docs/index.rst:
--------------------------------------------------------------------------------
1 | Django ORM Cookbook is a book about doing things with Django ORM and Django models.
2 | Django is a “MTV” (Model-Template-View) framework – This book provides a deep dive into the :code:`M` part.
3 |
4 | They take the form of about 50 questions of the form :code:`How to do X with Django ORM/Queryset/Models`.
5 |
6 |
7 |
8 | Database Modelling
9 | ===============================================
10 |
11 | .. toctree::
12 | :maxdepth: 1
13 | :numbered:
14 |
15 | one_to_one
16 | one_to_many
17 | many_to_many
18 | self_fk
19 | existing_database
20 | database_view
21 | generic_models
22 | table_name
23 | column_name
24 | null_vs_blank
25 | uuid
26 | slugfield
27 | multiple_databases
28 |
29 |
30 |
31 | Querying and Filtering
32 | ===============================================
33 |
34 | .. toctree::
35 | :maxdepth: 1
36 | :numbered:
37 |
38 | query
39 | or_query
40 | and_query
41 | notequal_query
42 | union
43 | select_some_fields
44 | subquery
45 | f_query
46 | filefield
47 | join
48 | second_largest
49 | duplicate
50 | distinct
51 | query_relatedtool
52 | agregation
53 | datetime
54 | random
55 | func_expressions
56 |
57 | Ordering things
58 | ========================
59 |
60 | .. toctree::
61 | :maxdepth: 1
62 | :numbered:
63 |
64 | asc_or_desc
65 | case_insensitive
66 | order_by_two
67 | order_by_related_model
68 | order_by_annotated_field
69 |
70 |
71 | Creating, Updating and Deleting things
72 | ===============================================
73 |
74 | .. toctree::
75 | :maxdepth: 1
76 | :numbered:
77 |
78 | multiple_objects
79 | copy
80 | singleton
81 | update_denormalized_fields
82 | truncate
83 | signals
84 |
85 | Testing
86 | ===============================================
87 | .. toctree::
88 | :maxdepth: 1
89 | :numbered:
90 |
91 | numqueries
92 | keepdb
93 | refresh_from_db
94 | initial_data
95 |
96 | Indices and tables
97 | ==================
98 |
99 | * :ref:`genindex`
100 | * :ref:`modindex`
101 | * :ref:`search`
102 |
--------------------------------------------------------------------------------
/heroes_and_monsters/events/models.py:
--------------------------------------------------------------------------------
1 | from django.db import models
2 | from django.utils.text import slugify
3 | from entities.models import Hero, Villain
4 | from django.contrib.auth.models import User
5 | import uuid
6 |
7 | class Epic(models.Model):
8 | name = models.CharField(max_length=255)
9 | participating_heroes = models.ManyToManyField(Hero)
10 | participating_villains = models.ManyToManyField(Villain)
11 |
12 |
13 | class Event(models.Model):
14 | id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
15 | epic = models.ForeignKey(Epic, on_delete=models.CASCADE)
16 | details = models.TextField()
17 | years_ago = models.PositiveIntegerField()
18 |
19 |
20 | class EventHero(models.Model):
21 | event = models.ForeignKey(Event, on_delete=models.CASCADE)
22 | hero = models.ForeignKey(Hero, on_delete=models.CASCADE)
23 | is_primary = models.BooleanField()
24 |
25 |
26 | class EventVillain(models.Model):
27 | event = models.ForeignKey(Event, on_delete=models.CASCADE)
28 | hero = models.ForeignKey(Villain, on_delete=models.CASCADE)
29 | is_primary = models.BooleanField()
30 |
31 |
32 | class UserParent(models.Model):
33 | user = models.OneToOneField(
34 | User,
35 | on_delete=models.CASCADE,
36 | primary_key=True,
37 | )
38 | father_name = models.CharField(max_length=100)
39 | mother_name = models.CharField(max_length=100)
40 |
41 | class Article(models.Model):
42 | headline = models.CharField(max_length=100)
43 | pub_date = models.DateField()
44 | reporter = models.ForeignKey(User, on_delete=models.CASCADE, related_name='reporter')
45 | slug = models.SlugField()
46 |
47 | def save(self, *args, **kwargs):
48 | self.slug = slugify(self.headline)
49 | super(Article, self).save(*args, **kwargs)
50 | def __str__(self):
51 | return self.headline
52 |
53 | class Meta:
54 | ordering = ('headline',)
55 |
56 | class TempUser(models.Model):
57 | first_name = models.CharField(max_length=100)
58 |
59 | class Meta:
60 | managed = False
61 | db_table = "temp_user"
62 |
63 |
64 | class ColumnName(models.Model):
65 | a = models.CharField(max_length=40,db_column='column1')
66 | column2 = models.CharField(max_length=50)
67 |
68 | def __str__(self):
69 | return self.a
70 |
--------------------------------------------------------------------------------
/heroes_and_monsters/events/migrations/0001_initial.py:
--------------------------------------------------------------------------------
1 | # Generated by Django 2.0.1 on 2018-01-31 11:13
2 |
3 | from django.db import migrations, models
4 | import django.db.models.deletion
5 |
6 |
7 | class Migration(migrations.Migration):
8 |
9 | initial = True
10 |
11 | dependencies = [
12 | ('entities', '0001_initial'),
13 | ]
14 |
15 | operations = [
16 | migrations.CreateModel(
17 | name='Epic',
18 | fields=[
19 | ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
20 | ('name', models.CharField(max_length=255)),
21 | ('participating_heroes', models.ManyToManyField(to='entities.Hero')),
22 | ('participating_villains', models.ManyToManyField(to='entities.Villain')),
23 | ],
24 | ),
25 | migrations.CreateModel(
26 | name='Event',
27 | fields=[
28 | ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
29 | ('details', models.TextField()),
30 | ('years_ago', models.PositiveIntegerField()),
31 | ('epic', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='events.Epic')),
32 | ],
33 | ),
34 | migrations.CreateModel(
35 | name='EventHero',
36 | fields=[
37 | ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
38 | ('is_primary', models.BooleanField()),
39 | ('event', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='events.Event')),
40 | ('hero', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='entities.Hero')),
41 | ],
42 | ),
43 | migrations.CreateModel(
44 | name='EventVillain',
45 | fields=[
46 | ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
47 | ('is_primary', models.BooleanField()),
48 | ('event', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='events.Event')),
49 | ('hero', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='entities.Villain')),
50 | ],
51 | ),
52 | ]
53 |
--------------------------------------------------------------------------------
/docs/many_to_many.rst:
--------------------------------------------------------------------------------
1 | How to model many to many relationships?
2 | ===============================================
3 |
4 | A many-to-many relationship refers to a relationship between tables in a database when a parent row in one table contains several child rows in the second table, and vice versa. ::
5 |
6 | Just to make it more interactive, we will talk about a twitter app. By just using few fields and ManyToMany field we can make a simple twitter app.
7 |
8 | We basically have 3 basic things in Twitter, tweets, followers, favourite/unfavourite.
9 |
10 | We have two models to make everything work. We are inheriting django's auth_user.::
11 |
12 | class User(AbstractUser):
13 | tweet = models.ManyToManyField(Tweet, blank=True)
14 | follower = models.ManyToManyField(settings.AUTH_USER_MODEL, blank=True)
15 | pass
16 |
17 | class Tweet(models.Model):
18 | tweet = models.TextField()
19 | favourite = models.ManyToManyField(settings.AUTH_USER_MODEL, blank=True, related_name='user_favourite')
20 |
21 | def __unicode__(self):
22 | return self.tweet
23 |
24 | What will the above model be able to do ? ::
25 |
26 | 1) User will able to follow/unfollow other users.
27 | 2) User will able to see tweets made by other users whom user is following.
28 | 3) User is able to favorite/unfavorite tweets.
29 |
30 |
31 | Few operations using ManyToManyfield which can be done are: ::
32 |
33 | >>> t1 = Tweet(tweet="I am happy today")
34 | >>> t1.save()
35 | >>> t2 = Tweet(tweet="This is my second Tweet")
36 | >>> t2.save()
37 | >>> u1 = User(username='johny1', first_name='Johny', last_name='Smith', email='johny@example.com')
38 | >>> u1.save()
39 | >>> u2 = User(username='johny1', first_name='Johny', last_name='Smith', email='johny@example.com')
40 | >>> u2.save()
41 | >>> u3 = User(username='someuser', first_name='Some', last_name='User', email='some@example.com')
42 | >>> u3.save()
43 |
44 | We have created few tweets and few users, that didn't involve any use of M2M field so far. Lets continue linking them in next step. ::
45 |
46 | >>> u2.tweet.add(t1)
47 | >>> u2.save()
48 | >>> u2.tweet.add(t2)
49 | >>> u2.save()
50 | // User can follow other users.
51 | >>> u2.follow.add(u1)
52 | >>> u2.save()
53 | // Tweets are linked to the users. Users have folloewd each other. Now we can make users do favourite/unfavourite of the tweets.
54 | >>> t1.favourite.add(u1)
55 | >>> t1.save()
56 | >>> t1.favourite.add(u3)
57 | >>> t1.save()
58 | // For removing any users vote
59 | >>> t1.favourite.remove(u1)
60 | >>> t1.save()
61 |
62 | Working example can be found in the repo: https://github.com/yashrastogi16/simpletwitter
--------------------------------------------------------------------------------
/docs/multiple_databases.rst:
--------------------------------------------------------------------------------
1 | How to add multiple databases to the django application ?
2 | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
3 |
4 | The configuration of database related stuff is mostly done in :code:`settings.py` file. So to add multiple database to our django project we need add them in :code:`DATABASES` dictionary. ::
5 |
6 | DATABASE_ROUTERS = ['path.to.DemoRouter']
7 | DATABASE_APPS_MAPPING = {'user_data': 'users_db',
8 | 'customer_data':'customers_db'}
9 |
10 | DATABASES = {
11 | 'default': {
12 | 'ENGINE': 'django.db.backends.sqlite3',
13 | 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
14 | },
15 | 'users_db': {
16 | 'NAME': 'user_data',
17 | 'ENGINE': 'django.db.backends.postgresql',
18 | 'USER': 'postgres_user',
19 | 'PASSWORD': 'password'
20 | },
21 | 'customers_db': {
22 | 'NAME': 'customer_data',
23 | 'ENGINE': 'django.db.backends.mysql',
24 | 'USER': 'mysql_cust',
25 | 'PASSWORD': 'root'
26 | }
27 | }
28 |
29 | With multiple databases it will be good to talk about :code:`Database Router`. The default routing scheme ensures that if a database isn’t specified, all queries fall back to the default database. :code:`Database Router` defaults to :code:`[]`. ::
30 |
31 | class DemoRouter:
32 | """
33 | A router to control all database operations on models in the
34 | user application.
35 | """
36 | def db_for_read(self, model, **hints):
37 | """
38 | Attempts to read user models go to users_db.
39 | """
40 | if model._meta.app_label == 'user_data':
41 | return 'users_db'
42 | return None
43 |
44 | def db_for_write(self, model, **hints):
45 | """
46 | Attempts to write user models go to users_db.
47 | """
48 | if model._meta.app_label == 'user_data':
49 | return 'users_db'
50 | return None
51 |
52 | def allow_relation(self, obj1, obj2, **hints):
53 | """
54 | Allow relations if a model in the user app is involved.
55 | """
56 | if obj1._meta.app_label == 'user_data' or \
57 | obj2._meta.app_label == 'user_data':
58 | return True
59 | return None
60 |
61 | def allow_migrate(self, db, app_label, model_name=None, **hints):
62 | """
63 | Make sure the auth app only appears in the 'users_db'
64 | database.
65 | """
66 | if app_label == 'user_data':
67 | return db == 'users_db'
68 | return None
69 |
70 |
71 | Respective models would be modified as ::
72 |
73 | class User(models.Model):
74 | username = models.Charfield(ax_length=100)
75 | . . .
76 | class Meta:
77 | app_label = 'user_data'
78 |
79 | class Customer(models.Model):
80 | name = models.TextField(max_length=100)
81 | . . .
82 | class Meta:
83 | app_label = 'customer_data'
84 |
85 | Few helpful commnds while working with multiple databases. ::
86 |
87 | $ ./manage.py migrate --database=users_db
88 |
--------------------------------------------------------------------------------
/heroes_and_monsters/entities/models.py:
--------------------------------------------------------------------------------
1 | from django.db import models
2 |
3 | from django.conf import settings
4 |
5 |
6 | class Category(models.Model):
7 | name = models.CharField(max_length=100)
8 |
9 | class Meta:
10 | verbose_name_plural = "Categories"
11 |
12 | def __str__(self):
13 | return self.name
14 |
15 |
16 | class Origin(models.Model):
17 | name = models.CharField(max_length=100)
18 |
19 | def __str__(self):
20 | return self.name
21 |
22 |
23 | class Entity(models.Model):
24 | GENDER_MALE = "Male"
25 | GENDER_FEMALE = "Female"
26 | GENDER_OTHERS = "Others/Unknown"
27 |
28 | name = models.CharField(max_length=100)
29 | alternative_name = models.CharField(
30 | max_length=100, null=True, blank=True
31 | )
32 |
33 |
34 | category = models.ForeignKey(Category, on_delete=models.CASCADE)
35 | origin = models.ForeignKey(Origin, on_delete=models.CASCADE)
36 | gender = models.CharField(
37 | max_length=100,
38 | choices=(
39 | (GENDER_MALE, GENDER_MALE),
40 | (GENDER_FEMALE, GENDER_FEMALE),
41 | (GENDER_OTHERS, GENDER_OTHERS),
42 | )
43 | )
44 | description = models.TextField()
45 |
46 | added_by = models.ForeignKey(settings.AUTH_USER_MODEL,
47 | null=True, blank=True, on_delete=models.SET_NULL)
48 | added_on = models.DateField(auto_now=True)
49 |
50 | def __str__(self):
51 | return self.name
52 |
53 | class Meta:
54 | abstract = True
55 |
56 |
57 | class Hero(Entity):
58 |
59 | class Meta:
60 | verbose_name_plural = "Heroes"
61 |
62 | is_immortal = models.BooleanField(default=True)
63 |
64 | benevolence_factor = models.PositiveSmallIntegerField(
65 | help_text="How benevolent this hero is?"
66 | )
67 | arbitrariness_factor = models.PositiveSmallIntegerField(
68 | help_text="How arbitrary this hero is?"
69 | )
70 |
71 | headshot = models.ImageField(null=True, blank=True, upload_to="hero_headshots/")
72 |
73 | # relationships
74 | father = models.ForeignKey(
75 | "self", related_name="children", null=True, blank=True, on_delete=models.SET_NULL
76 | )
77 | mother = models.ForeignKey(
78 | "self", related_name="+", null=True, blank=True, on_delete=models.SET_NULL
79 | )
80 | spouse = models.ForeignKey(
81 | "self", related_name="+", null=True, blank=True, on_delete=models.SET_NULL
82 | )
83 |
84 |
85 | class HeroProxy(Hero):
86 |
87 | class Meta:
88 | proxy = True
89 |
90 | class Villain(Entity):
91 | is_immortal = models.BooleanField(default=False)
92 |
93 | malevolence_factor = models.PositiveSmallIntegerField(
94 | help_text="How malevolent this villain is?"
95 | )
96 | power_factor = models.PositiveSmallIntegerField(
97 | help_text="How powerful this villain is?"
98 | )
99 | is_unique = models.BooleanField(default=True)
100 | count = models.PositiveSmallIntegerField(default=1)
101 |
102 |
103 | class HeroAcquaintance(models.Model):
104 | "Non family contacts of a Hero"
105 | hero = models.OneToOneField(Hero, on_delete=models.CASCADE)
106 |
107 | friends = models.ManyToManyField(Hero, related_name="+")
108 | detractors = models.ManyToManyField(Hero, related_name="+")
109 | main_anatagonists = models.ManyToManyField(Villain, related_name="+")
110 |
111 |
112 | class AllEntity(models.Model):
113 | name = models.CharField(max_length=100)
114 |
115 | class Meta:
116 | managed = False
117 | db_table = "entities_entity"
118 |
--------------------------------------------------------------------------------
/heroes_and_monsters/heroes_and_monsters/settings.py:
--------------------------------------------------------------------------------
1 | """
2 | Django settings for heroes_and_monsters project.
3 |
4 | Generated by 'django-admin startproject' using Django 2.0.1.
5 |
6 | For more information on this file, see
7 | https://docs.djangoproject.com/en/2.0/topics/settings/
8 |
9 | For the full list of settings and their values, see
10 | https://docs.djangoproject.com/en/2.0/ref/settings/
11 | """
12 |
13 | import os
14 |
15 | # Build paths inside the project like this: os.path.join(BASE_DIR, ...)
16 | BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
17 |
18 |
19 | # Quick-start development settings - unsuitable for production
20 | # See https://docs.djangoproject.com/en/2.0/howto/deployment/checklist/
21 |
22 | # SECURITY WARNING: keep the secret key used in production secret!
23 | SECRET_KEY = 'jj3%i453q08gh20n75pt27dx8k*6d4d+gepevvv6t)b#42oy(8'
24 |
25 | # SECURITY WARNING: don't run with debug turned on in production!
26 | DEBUG = True
27 |
28 | ALLOWED_HOSTS = []
29 |
30 |
31 | # Application definition
32 |
33 | INSTALLED_APPS = [
34 | 'django.contrib.admin',
35 | 'django.contrib.auth',
36 | 'django.contrib.contenttypes',
37 | 'django.contrib.sessions',
38 | 'django.contrib.messages',
39 | 'django.contrib.staticfiles',
40 |
41 | 'entities',
42 | 'events',
43 |
44 | 'django_extensions',
45 | ]
46 |
47 | MIDDLEWARE = [
48 | 'django.middleware.security.SecurityMiddleware',
49 | 'django.contrib.sessions.middleware.SessionMiddleware',
50 | 'django.middleware.common.CommonMiddleware',
51 | 'django.middleware.csrf.CsrfViewMiddleware',
52 | 'django.contrib.auth.middleware.AuthenticationMiddleware',
53 | 'django.contrib.messages.middleware.MessageMiddleware',
54 | 'django.middleware.clickjacking.XFrameOptionsMiddleware',
55 | ]
56 |
57 | ROOT_URLCONF = 'heroes_and_monsters.urls'
58 |
59 | TEMPLATES = [
60 | {
61 | 'BACKEND': 'django.template.backends.django.DjangoTemplates',
62 | 'DIRS': [os.path.join(BASE_DIR, 'templates/')],
63 | 'APP_DIRS': True,
64 | 'OPTIONS': {
65 | 'context_processors': [
66 | 'django.template.context_processors.debug',
67 | 'django.template.context_processors.request',
68 | 'django.contrib.auth.context_processors.auth',
69 | 'django.contrib.messages.context_processors.messages',
70 | ],
71 | },
72 | },
73 | ]
74 |
75 | WSGI_APPLICATION = 'heroes_and_monsters.wsgi.application'
76 |
77 |
78 | # Database
79 | # https://docs.djangoproject.com/en/2.0/ref/settings/#databases
80 |
81 | DATABASES = {
82 | 'default': {
83 | 'ENGINE': 'django.db.backends.sqlite3',
84 | 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
85 | }
86 | }
87 |
88 |
89 | # Password validation
90 | # https://docs.djangoproject.com/en/2.0/ref/settings/#auth-password-validators
91 |
92 | AUTH_PASSWORD_VALIDATORS = [
93 | {
94 | 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
95 | },
96 | {
97 | 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
98 | },
99 | {
100 | 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
101 | },
102 | {
103 | 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
104 | },
105 | ]
106 |
107 |
108 | # Internationalization
109 | # https://docs.djangoproject.com/en/2.0/topics/i18n/
110 |
111 | LANGUAGE_CODE = 'en-us'
112 |
113 | TIME_ZONE = 'UTC'
114 |
115 | USE_I18N = True
116 |
117 | USE_L10N = True
118 |
119 | USE_TZ = True
120 |
121 |
122 | # Static files (CSS, JavaScript, Images)
123 | # https://docs.djangoproject.com/en/2.0/howto/static-files/
124 |
125 | STATIC_URL = '/static/'
126 | STATICFILES_DIRS = [
127 | os.path.join(BASE_DIR, "static"),
128 | ]
129 |
130 | MEDIA_URL = "/media/"
131 | MEDIA_ROOT = os.path.join(BASE_DIR, "media")
132 |
--------------------------------------------------------------------------------
/heroes_and_monsters/entities/migrations/0002_auto_20180221_1830.py:
--------------------------------------------------------------------------------
1 | # Generated by Django 2.0 on 2018-02-21 18:30
2 |
3 | from django.conf import settings
4 | from django.db import migrations, models
5 | import django.db.models.deletion
6 |
7 |
8 | class Migration(migrations.Migration):
9 |
10 | dependencies = [
11 | migrations.swappable_dependency(settings.AUTH_USER_MODEL),
12 | ('entities', '0001_initial'),
13 | ]
14 |
15 | operations = [
16 | migrations.CreateModel(
17 | name='AllEntity',
18 | fields=[
19 | ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
20 | ('name', models.CharField(max_length=100)),
21 | ],
22 | options={
23 | 'db_table': 'entities_entity',
24 | 'managed': False,
25 | },
26 | ),
27 | migrations.CreateModel(
28 | name='HeroAcquaintance',
29 | fields=[
30 | ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
31 | ],
32 | ),
33 | migrations.CreateModel(
34 | name='HeroProxy',
35 | fields=[
36 | ],
37 | options={
38 | 'proxy': True,
39 | 'indexes': [],
40 | },
41 | bases=('entities.hero',),
42 | ),
43 | migrations.AlterModelOptions(
44 | name='category',
45 | options={'verbose_name_plural': 'Categories'},
46 | ),
47 | migrations.AlterModelOptions(
48 | name='hero',
49 | options={'verbose_name_plural': 'Heroes'},
50 | ),
51 | migrations.AddField(
52 | model_name='hero',
53 | name='added_by',
54 | field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to=settings.AUTH_USER_MODEL),
55 | ),
56 | migrations.AddField(
57 | model_name='hero',
58 | name='added_on',
59 | field=models.DateField(auto_now=True),
60 | ),
61 | migrations.AddField(
62 | model_name='hero',
63 | name='headshot',
64 | field=models.ImageField(blank=True, null=True, upload_to='hero_headshots/'),
65 | ),
66 | migrations.AddField(
67 | model_name='villain',
68 | name='added_by',
69 | field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to=settings.AUTH_USER_MODEL),
70 | ),
71 | migrations.AddField(
72 | model_name='villain',
73 | name='added_on',
74 | field=models.DateField(auto_now=True),
75 | ),
76 | migrations.AlterField(
77 | model_name='hero',
78 | name='father',
79 | field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='children', to='entities.Hero'),
80 | ),
81 | migrations.AddField(
82 | model_name='heroacquaintance',
83 | name='detractors',
84 | field=models.ManyToManyField(related_name='_heroacquaintance_detractors_+', to='entities.Hero'),
85 | ),
86 | migrations.AddField(
87 | model_name='heroacquaintance',
88 | name='friends',
89 | field=models.ManyToManyField(related_name='_heroacquaintance_friends_+', to='entities.Hero'),
90 | ),
91 | migrations.AddField(
92 | model_name='heroacquaintance',
93 | name='hero',
94 | field=models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to='entities.Hero'),
95 | ),
96 | migrations.AddField(
97 | model_name='heroacquaintance',
98 | name='main_anatagonists',
99 | field=models.ManyToManyField(related_name='_heroacquaintance_main_anatagonists_+', to='entities.Villain'),
100 | ),
101 | ]
102 |
--------------------------------------------------------------------------------
/heroes_and_monsters/entities/migrations/0001_initial.py:
--------------------------------------------------------------------------------
1 | # Generated by Django 2.0.1 on 2018-01-31 11:13
2 |
3 | from django.db import migrations, models
4 | import django.db.models.deletion
5 |
6 |
7 | class Migration(migrations.Migration):
8 |
9 | initial = True
10 |
11 | dependencies = [
12 | ]
13 |
14 | operations = [
15 | migrations.CreateModel(
16 | name='Category',
17 | fields=[
18 | ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
19 | ('name', models.CharField(max_length=100)),
20 | ],
21 | ),
22 | migrations.CreateModel(
23 | name='Hero',
24 | fields=[
25 | ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
26 | ('name', models.CharField(max_length=100)),
27 | ('alternative_name', models.CharField(blank=True, max_length=100, null=True)),
28 | ('gender', models.CharField(choices=[('Male', 'Male'), ('Female', 'Female'), ('Others/Unknown', 'Others/Unknown')], max_length=100)),
29 | ('description', models.TextField()),
30 | ('is_immortal', models.BooleanField(default=True)),
31 | ('benevolence_factor', models.PositiveSmallIntegerField(help_text='How benevolent this hero is?')),
32 | ('arbitrariness_factor', models.PositiveSmallIntegerField(help_text='How arbitrary this hero is?')),
33 | ('category', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='entities.Category')),
34 | ('father', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='entities.Hero')),
35 | ('mother', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='entities.Hero')),
36 | ],
37 | options={
38 | 'abstract': False,
39 | },
40 | ),
41 | migrations.CreateModel(
42 | name='Origin',
43 | fields=[
44 | ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
45 | ('name', models.CharField(max_length=100)),
46 | ],
47 | ),
48 | migrations.CreateModel(
49 | name='Villain',
50 | fields=[
51 | ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
52 | ('name', models.CharField(max_length=100)),
53 | ('alternative_name', models.CharField(blank=True, max_length=100, null=True)),
54 | ('gender', models.CharField(choices=[('Male', 'Male'), ('Female', 'Female'), ('Others/Unknown', 'Others/Unknown')], max_length=100)),
55 | ('description', models.TextField()),
56 | ('is_immortal', models.BooleanField(default=False)),
57 | ('malevolence_factor', models.PositiveSmallIntegerField(help_text='How malevolent this villain is?')),
58 | ('power_factor', models.PositiveSmallIntegerField(help_text='How powerful this villain is?')),
59 | ('is_unique', models.BooleanField(default=True)),
60 | ('count', models.PositiveSmallIntegerField(default=1)),
61 | ('category', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='entities.Category')),
62 | ('origin', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='entities.Origin')),
63 | ],
64 | options={
65 | 'abstract': False,
66 | },
67 | ),
68 | migrations.AddField(
69 | model_name='hero',
70 | name='origin',
71 | field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='entities.Origin'),
72 | ),
73 | migrations.AddField(
74 | model_name='hero',
75 | name='spouse',
76 | field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='entities.Hero'),
77 | ),
78 | ]
79 |
--------------------------------------------------------------------------------
/docs/conf.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 | # -*- coding: utf-8 -*-
3 | #
4 | # Django ORM Cookbook documentation build configuration file, created by
5 | # sphinx-quickstart on Mon Feb 26 10:14:54 2018.
6 | #
7 | # This file is execfile()d with the current directory set to its
8 | # containing dir.
9 | #
10 | # Note that not all possible configuration values are present in this
11 | # autogenerated file.
12 | #
13 | # All configuration values have a default; values that are commented out
14 | # serve to show the default.
15 |
16 | # If extensions (or modules to document with autodoc) are in another directory,
17 | # add these directories to sys.path here. If the directory is relative to the
18 | # documentation root, use os.path.abspath to make it absolute, like shown here.
19 | #
20 | # import os
21 | # import sys
22 | # sys.path.insert(0, os.path.abspath('.'))
23 |
24 |
25 | # -- General configuration ------------------------------------------------
26 |
27 | # If your documentation needs a minimal Sphinx version, state it here.
28 | #
29 | # needs_sphinx = '1.0'
30 |
31 | # Add any Sphinx extension module names here, as strings. They can be
32 | # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
33 | # ones.
34 | extensions = []
35 |
36 | # Add any paths that contain templates here, relative to this directory.
37 | templates_path = ['_templates']
38 |
39 | # The suffix(es) of source filenames.
40 | # You can specify multiple suffix as a list of string:
41 | #
42 | # source_suffix = ['.rst', '.md']
43 | source_suffix = '.rst'
44 |
45 | # The master toctree document.
46 | master_doc = 'index'
47 |
48 | # General information about the project.
49 | project = 'Django ORM Cookbook'
50 | copyright = '2018, Agiliq'
51 | author = 'Agiliq'
52 |
53 | # The version info for the project you're documenting, acts as replacement for
54 | # |version| and |release|, also used in various other places throughout the
55 | # built documents.
56 | #
57 | # The short X.Y version.
58 | version = '2.0'
59 | # The full version, including alpha/beta/rc tags.
60 | release = '2.0'
61 |
62 | # The language for content autogenerated by Sphinx. Refer to documentation
63 | # for a list of supported languages.
64 | #
65 | # This is also used if you do content translation via gettext catalogs.
66 | # Usually you set "language" from the command line for these cases.
67 | language = None
68 |
69 | # List of patterns, relative to source directory, that match files and
70 | # directories to ignore when looking for source files.
71 | # This patterns also effect to html_static_path and html_extra_path
72 | exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store']
73 |
74 | # The name of the Pygments (syntax highlighting) style to use.
75 | pygments_style = 'sphinx'
76 |
77 | # If true, `todo` and `todoList` produce output, else they produce nothing.
78 | todo_include_todos = False
79 |
80 |
81 | # -- Options for HTML output ----------------------------------------------
82 |
83 | # The theme to use for HTML and HTML Help pages. See the documentation for
84 | # a list of builtin themes.
85 | #
86 | html_theme = 'sphinx_rtd_theme'
87 |
88 |
89 | # Theme options are theme-specific and customize the look and feel of a theme
90 | # further. For a list of options available for each theme, see the
91 | # documentation.
92 | #
93 | # html_theme_options = {}
94 |
95 | # Add any paths that contain custom static files (such as style sheets) here,
96 | # relative to this directory. They are copied after the builtin static files,
97 | # so a file named "default.css" will overwrite the builtin "default.css".
98 | html_static_path = ['_static']
99 |
100 | # Custom sidebar templates, must be a dictionary that maps document names
101 | # to template names.
102 | #
103 | # This is required for the alabaster theme
104 | # refs: http://alabaster.readthedocs.io/en/latest/installation.html#sidebars
105 | html_sidebars = {
106 | '**': [
107 | 'relations.html', # needs 'show_related': True theme option to display
108 | 'searchbox.html',
109 | ]
110 | }
111 |
112 |
113 | # -- Options for HTMLHelp output ------------------------------------------
114 |
115 | # Output file base name for HTML help builder.
116 | htmlhelp_basename = 'DjangoORMCookbookdoc'
117 |
118 |
119 | # -- Options for LaTeX output ---------------------------------------------
120 |
121 | latex_elements = {
122 | # The paper size ('letterpaper' or 'a4paper').
123 | #
124 | # 'papersize': 'letterpaper',
125 |
126 | # The font size ('10pt', '11pt' or '12pt').
127 | #
128 | # 'pointsize': '10pt',
129 |
130 | # Additional stuff for the LaTeX preamble.
131 | #
132 | # 'preamble': '',
133 |
134 | # Latex figure (float) alignment
135 | #
136 | # 'figure_align': 'htbp',
137 | }
138 |
139 | # Grouping the document tree into LaTeX files. List of tuples
140 | # (source start file, target name, title,
141 | # author, documentclass [howto, manual, or own class]).
142 | latex_documents = [
143 | (master_doc, 'DjangoORMCookbook.tex', 'Django ORM Cookbook Documentation',
144 | 'Agiliq', 'manual'),
145 | ]
146 |
147 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | ### Django ORM cookbook
2 |
3 |
4 | Django ORM cookbook is a set of recipes of how to do things with Django.
5 | They take the form of about 50 questions of the form
6 | `How to do X with Django ORM/Queryset`.
7 |
8 | We have a set of models which we use across the book for answering these questions.
9 |
10 | ### The models
11 |
12 | You plan to write a set of models and an assoicated admin for UMSRA researchers. You come up with two apps `entities` and `events`. The models are
13 |
14 |
15 | #### Events
16 |
17 |
18 | from django.db import models
19 | from django.utils.text import slugify
20 | from entities.models import Hero, Villain
21 | from django.contrib.auth.models import User
22 | import uuid
23 |
24 | class Epic(models.Model):
25 | name = models.CharField(max_length=255)
26 | participating_heroes = models.ManyToManyField(Hero)
27 | participating_villains = models.ManyToManyField(Villain)
28 |
29 |
30 | class Event(models.Model):
31 | id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
32 | epic = models.ForeignKey(Epic, on_delete=models.CASCADE)
33 | details = models.TextField()
34 | years_ago = models.PositiveIntegerField()
35 |
36 |
37 | class EventHero(models.Model):
38 | event = models.ForeignKey(Event, on_delete=models.CASCADE)
39 | hero = models.ForeignKey(Hero, on_delete=models.CASCADE)
40 | is_primary = models.BooleanField()
41 |
42 |
43 | class EventVillain(models.Model):
44 | event = models.ForeignKey(Event, on_delete=models.CASCADE)
45 | hero = models.ForeignKey(Villain, on_delete=models.CASCADE)
46 | is_primary = models.BooleanField()
47 |
48 |
49 | class UserParent(models.Model):
50 | user = models.OneToOneField(
51 | User,
52 | on_delete=models.CASCADE,
53 | primary_key=True,
54 | )
55 | father_name = models.CharField(max_length=100)
56 | mother_name = models.CharField(max_length=100)
57 |
58 | class Article(models.Model):
59 | headline = models.CharField(max_length=100)
60 | pub_date = models.DateField()
61 | reporter = models.ForeignKey(User, on_delete=models.CASCADE, related_name='reporter')
62 | slug = models.SlugField()
63 |
64 | def save(self, *args, **kwargs):
65 | self.slug = slugify(self.headline)
66 | super(Article, self).save(*args, **kwargs)
67 | def __str__(self):
68 | return self.headline
69 |
70 | class Meta:
71 | ordering = ('headline',)
72 |
73 | class TempUser(models.Model):
74 | first_name = models.CharField(max_length=100)
75 |
76 | class Meta:
77 | managed = False
78 | db_table = "temp_user"
79 |
80 |
81 | class ColumnName(models.Model):
82 | a = models.CharField(max_length=40,db_column='column1')
83 | column2 = models.CharField(max_length=50)
84 |
85 | def __str__(self):
86 | return self.a
87 |
88 |
89 | #### Entities
90 |
91 | from django.db import models
92 |
93 | from django.conf import settings
94 |
95 |
96 | class Category(models.Model):
97 | name = models.CharField(max_length=100)
98 |
99 | class Meta:
100 | verbose_name_plural = "Categories"
101 |
102 | def __str__(self):
103 | return self.name
104 |
105 |
106 | class Origin(models.Model):
107 | name = models.CharField(max_length=100)
108 |
109 | def __str__(self):
110 | return self.name
111 |
112 |
113 | class Entity(models.Model):
114 | GENDER_MALE = "Male"
115 | GENDER_FEMALE = "Female"
116 | GENDER_OTHERS = "Others/Unknown"
117 |
118 | name = models.CharField(max_length=100)
119 | alternative_name = models.CharField(
120 | max_length=100, null=True, blank=True
121 | )
122 |
123 |
124 | category = models.ForeignKey(Category, on_delete=models.CASCADE)
125 | origin = models.ForeignKey(Origin, on_delete=models.CASCADE)
126 | gender = models.CharField(
127 | max_length=100,
128 | choices=(
129 | (GENDER_MALE, GENDER_MALE),
130 | (GENDER_FEMALE, GENDER_FEMALE),
131 | (GENDER_OTHERS, GENDER_OTHERS),
132 | )
133 | )
134 | description = models.TextField()
135 |
136 | added_by = models.ForeignKey(settings.AUTH_USER_MODEL,
137 | null=True, blank=True, on_delete=models.SET_NULL)
138 | added_on = models.DateField(auto_now=True)
139 |
140 | def __str__(self):
141 | return self.name
142 |
143 | class Meta:
144 | abstract = True
145 |
146 |
147 | class Hero(Entity):
148 |
149 | class Meta:
150 | verbose_name_plural = "Heroes"
151 |
152 | is_immortal = models.BooleanField(default=True)
153 |
154 | benevolence_factor = models.PositiveSmallIntegerField(
155 | help_text="How benevolent this hero is?"
156 | )
157 | arbitrariness_factor = models.PositiveSmallIntegerField(
158 | help_text="How arbitrary this hero is?"
159 | )
160 |
161 | headshot = models.ImageField(null=True, blank=True, upload_to="hero_headshots/")
162 |
163 | # relationships
164 | father = models.ForeignKey(
165 | "self", related_name="children", null=True, blank=True, on_delete=models.SET_NULL
166 | )
167 | mother = models.ForeignKey(
168 | "self", related_name="+", null=True, blank=True, on_delete=models.SET_NULL
169 | )
170 | spouse = models.ForeignKey(
171 | "self", related_name="+", null=True, blank=True, on_delete=models.SET_NULL
172 | )
173 |
174 |
175 | class HeroProxy(Hero):
176 |
177 | class Meta:
178 | proxy = True
179 |
180 | class Villain(Entity):
181 | is_immortal = models.BooleanField(default=False)
182 |
183 | malevolence_factor = models.PositiveSmallIntegerField(
184 | help_text="How malevolent this villain is?"
185 | )
186 | power_factor = models.PositiveSmallIntegerField(
187 | help_text="How powerful this villain is?"
188 | )
189 | is_unique = models.BooleanField(default=True)
190 | count = models.PositiveSmallIntegerField(default=1)
191 |
192 |
193 | class HeroAcquaintance(models.Model):
194 | "Non family contacts of a Hero"
195 | hero = models.OneToOneField(Hero, on_delete=models.CASCADE)
196 |
197 | friends = models.ManyToManyField(Hero, related_name="+")
198 | detractors = models.ManyToManyField(Hero, related_name="+")
199 | main_anatagonists = models.ManyToManyField(Villain, related_name="+")
200 |
201 |
202 | class AllEntity(models.Model):
203 | name = models.CharField(max_length=100)
204 |
205 | class Meta:
206 | managed = False
207 | db_table = "entities_entity"
208 |
--------------------------------------------------------------------------------