from datetime import date
from organizer.models import Tag, Startup, NewsLink
from blog.models import Post

"""
Explanation: Prepare Notebook
To run this code, written at the very end of Chapter 3, you need a working empty database.
To move the project into a valid state, please use the command git chapter [chapter-number] to find a valid commit. A commit at the end of Chapter 3, or any commit in Chapters 4-9, should work just fine. Use git checkout [commit] to change the state of the project. Once there, delete the database (if it exists).
$ rm db.sqlite3

To (re-)create the database:
$ ./manage.py migrate

Please see the Read Me file or the actual book for more details.
End of explanation
"""


edut = Tag(name='Education', slug='education')

edut

edut.save()

edut.delete()

edut  # still in memory!

"""
Explanation: Interacting With the Database
End of explanation
"""


type(Tag.objects)  # a model manager

Tag.objects.create(name='Video Games', slug='video-games')

# create multiple objects in a go!
Tag.objects.bulk_create([
    Tag(name='Django', slug='django'),
    Tag(name='Mobile', slug='mobile'),
    Tag(name='Web', slug='web'),
])

Tag.objects.all()

Tag.objects.all()[0]  # acts like a list

type(Tag.objects.all())  # is not a list

# managers are not accessible to model instances, only to model classes!
try:
    edut.objects
except AttributeError as e:
    print(e)

"""
Explanation: Creation and Destruction with Managers
End of explanation
"""


Tag.objects.all()

Tag.objects.count()

"""
Explanation: Methods of Data Retrieval
End of explanation
"""


Tag.objects.get(slug='django')

type(Tag.objects.all())

type(Tag.objects.get(slug='django'))

# case-sensitive!
try:
    Tag.objects.get(slug='Django')
except Tag.DoesNotExist as e:
    print(e)

# the i is for case-Insensitive
Tag.objects.get(slug__iexact='DJANGO')

Tag.objects.get(slug__istartswith='DJ')

Tag.objects.get(slug__contains='an')

# get always returns a single object
try:
    # djangO, mObile, videO-games
    Tag.objects.get(slug__contains='o')
except Tag.MultipleObjectsReturned as e:
    print(e)

"""
Explanation: The get method
End of explanation
"""


## unlike get, can fetch multiple objects
Tag.objects.filter(slug__contains='o')

type(Tag.objects.filter(slug__contains='o'))

"""
Explanation: The filter method
End of explanation
"""


Tag.objects.filter(slug__contains='o').order_by('-name')

# first we call order_by on the manager
Tag.objects.order_by('-name')

# now we call filter on the manager, and order the resulting queryset
Tag.objects.filter(slug__contains='e').order_by('-name')

"""
Explanation: Chaining Calls
End of explanation
"""


Tag.objects.values_list()

type(Tag.objects.values_list())

Tag.objects.values_list('name', 'slug')

Tag.objects.values_list('name')

Tag.objects.values_list('name', flat=True)

type(Tag.objects.values_list('name', flat=True))

"""
Explanation: values and values_list
End of explanation
"""


jb = Startup.objects.create(
    name='JamBon Software',
    slug='jambon-software',
    contact='django@jambonsw.com',
    description='Web and Mobile Consulting.\n'
                'Django Tutoring.\n',
    founded_date=date(2013, 1, 18),
    website='https://jambonsw.com/',
)
jb  # this output only clear because of __str__()

jb.founded_date

jb.founded_date = date(2014,1,1)
# we're not calling save() !
jb.founded_date

# get version in database
jb = Startup.objects.get(slug='jambon-software')
# work above is all for nought because we didn't save()
jb.founded_date

"""
Explanation: Data in Memory vs Data in the Database
End of explanation
"""


djt = Post.objects.create(
    title='Django Training',
    slug='django-training',
    text=(
        "Learn Django in a classroom setting "
        "with JamBon Software."),
)
djt

djt.pub_date = date(2013, 1, 18)
djt.save()
djt

type(djt.tags)

type(djt.startups)

djt.tags.all()

djt.startups.all()

django = Tag.objects.get(slug__contains='django')
djt.tags.add(django)
djt.tags.all()

django.blog_posts.all()  # a "reverse" relation

django.startup_set.add(jb)  # a "reverse" relation
django.startup_set.all()

jb.tags.all()  # the "forward" relation

# on more time, for repetition!
djt

# "forward" relation
djt.startups.add(jb)
djt.startups.all()

jb.blog_posts.all()  # "reverse" relation

"""
Explanation: Connecting Data through Relations
End of explanation
"""


