Slide 1

Slide 1 text

GDPR ! Django Eleni Lixourio, | @geekfish_ | Python DBBUG

Slide 2

Slide 2 text

GDPR? Eleni Lixourio, | @geekfish_ | Python DBBUG

Slide 3

Slide 3 text

No content

Slide 4

Slide 4 text

GDPR is about... cookie popups user data! Eleni Lixourio, | @geekfish_ | Python DBBUG

Slide 5

Slide 5 text

"Can I have my data?" — a user Eleni Lixourio, | @geekfish_ | Python DBBUG

Slide 6

Slide 6 text

"Umm yeah, if you could you fetch their data that'd be great" — a manager Eleni Lixourio, | @geekfish_ | Python DBBUG

Slide 7

Slide 7 text

Off to the Users table! Eleni Lixourio, | @geekfish_ | Python DBBUG

Slide 8

Slide 8 text

No content

Slide 9

Slide 9 text

It's not that I'm lazy... ...it's just that there's an easier way! Eleni Lixourio, | @geekfish_ | Python DBBUG

Slide 10

Slide 10 text

Django is already solving this! Eleni Lixourio, | @geekfish_ | Python DBBUG

Slide 11

Slide 11 text

class Book(models.Model): author = models.ForeignKey(User, on_delete=CASCADE) vs CREATE TABLE books ( FOREIGN KEY (author_id) REFERENCES users (id) ON DELETE CASCADE ); Eleni Lixourio, | @geekfish_ | Python DBBUG

Slide 12

Slide 12 text

ON DELETE CASCADE "No, thanks. I like mine be3er" — Django Eleni Lixourio, | @geekfish_ | Python DBBUG

Slide 13

Slide 13 text

Django admin • Please don't use it. ... but it does some things pre1y well Eleni Lixourio, | @geekfish_ | Python DBBUG

Slide 14

Slide 14 text

No content

Slide 15

Slide 15 text

Neat Eleni Lixourio, | @geekfish_ | Python DBBUG

Slide 16

Slide 16 text

from django.contrib.admin.utils import NestedObjects def collect_user_data(user): collector = NestedObjects(using="replica") collector.collect([user]) return collector.data > pprint(collect_user_data(user)) > OrderedDict([(, > {}), > (, > {, })]) Eleni Lixourio, | @geekfish_ | Python DBBUG

Slide 17

Slide 17 text

Expand! Eleni Lixourio, | @geekfish_ | Python DBBUG

Slide 18

Slide 18 text

def collect_user_data(user): collector = CustomUserCollector(user) collector.collect_all() return collector.data Eleni Lixourio, | @geekfish_ | Python DBBUG

Slide 19

Slide 19 text

from django.contrib.admin.utils import NestedObjects class CustomUserCollector(NestedObjects): def __init__(self, user, *args, **kwargs): self.user = user kwargs['using'] = "replica" super(CustomUserCollector, self).__init__(*args, **kwargs) def collect_all(): self.collect_from_db() self.collect_from_nonrel() self.collect_remote() # ... Eleni Lixourio, | @geekfish_ | Python DBBUG

Slide 20

Slide 20 text

# from myapp.housekeeping import collect, IP_ASSOCIATED_MODELS # class CustomUserCollector(NestedObjects): # ... def collect_from_db(self): self.collect([self.user]) for model in IP_ASSOCIATED_MODELS: self.collect( model.objects.filter(ip__in=self.user.known_ips)) def collect_from_nonrel(self): self.data['couchdb'] = collect.from_couchdb(user) self.data['redis_temp'] = collect.from_redis(user) def collect_remote(self): self.data['some_ext_service'] = collect.from_api(user) Eleni Lixourio, | @geekfish_ | Python DBBUG

Slide 21

Slide 21 text

Gotchas? ! Eleni Lixourio, | @geekfish_ | Python DBBUG

Slide 22

Slide 22 text

Thank you! • Ques&ons? • Read more: h"ps:/ /blog.eleni.co/gdpr-django-collector/ Eleni Lixourio, [email protected] @geekfish_ PS: Python Code Dojo: 21/11 via Bristol Codehub