diff --git a/Dockerfile b/Dockerfile
index 59005e65a70c62b7264a69468a2c0fa93f36c744..2c9d4ff9f78656a026c6a9ada9f2e662347a5035 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -8,7 +8,7 @@ ENV PYTHONUNBUFFERED 1
 COPY ./requirements.txt .
 
 RUN apk add --no-cache --virtual .build-deps \
-    gcc postgresql-dev libpq musl-dev \
+    gcc postgresql-dev libpq musl-dev jpeg-dev zlib-dev\
     && pip install --upgrade pip \
     && pip install -r requirements.txt \
     && find /usr/local \
diff --git a/docker-compose.yml b/docker-compose.yml
index c1527a1ba37f8615efacb1248dc67ed61ebfa98a..e280d565f44bf0cc8ef1b6aa4093a6712c60c5ec 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -9,6 +9,7 @@ services:
     volumes:
       - ./nginx/default.conf:/etc/nginx/conf.d/default.conf
       - staticfiles:/var/www/html/static/
+      - mediafiles:/var/www/html/media/
     depends_on:
       - backend
 
@@ -20,6 +21,7 @@ services:
     volumes:
       - ./:/app/backend/
       - staticfiles:/app/backend/staticfiles/
+      - mediafiles:/app/backend/mediafiles/
     env_file:
       - .env
     environment:
@@ -39,3 +41,4 @@ services:
 volumes:
   postgres_data:
   staticfiles:
+  mediafiles:
diff --git a/nginx/default.conf b/nginx/default.conf
index 4b5e6f7824de8d6b87d48144b37cd23fee6fb690..aef744de213ba0998d900d98af5ae84b99323ec4 100644
--- a/nginx/default.conf
+++ b/nginx/default.conf
@@ -5,6 +5,10 @@ server {
         root /var/www/html/;
     }
 
+    location /media/ {
+        root /var/www/html/;
+    }
+
     location / {
         proxy_pass http://backend:8000;
         proxy_set_header Host $http_host;
diff --git a/requirements.txt b/requirements.txt
index cb089eea7d140094d61e6c9a7f63484a036cadea..fca7eb3fda71c97e24e46ad160e659d6f53ec3c4 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -6,5 +6,6 @@ django-graphql-jwt==0.3.1
 graphene-django==2.10.1
 gunicorn==20.0.4
 psycopg2-binary==2.8.5
+Pillow==7.2.0
 pytz==2020.1
 sqlparse==0.3.1
diff --git a/sizakat/mustahik/admin.py b/sizakat/mustahik/admin.py
index 8c38f3f3dad51e4585f3984282c2a4bec5349c1e..bca847d3ffaf15fd0667cad74bf069b52a5dcedb 100644
--- a/sizakat/mustahik/admin.py
+++ b/sizakat/mustahik/admin.py
@@ -1,3 +1,17 @@
 from django.contrib import admin
 
-# Register your models here.
+from .models import (
+    Mustahik,
+    DataSource,
+    DataSourceWarga,
+    DataSourceInstitusi,
+    DataSourcePekerja,
+)
+
+admin.site.register([
+    Mustahik,
+    DataSource,
+    DataSourceWarga,
+    DataSourceInstitusi,
+    DataSourcePekerja,
+])
diff --git a/sizakat/mustahik/forms.py b/sizakat/mustahik/forms.py
index 9af65d63a6c0998df6c1a5cbbfc41a9a6504e78e..d6b1039618500006dc6564cb98f47701cd5beb83 100644
--- a/sizakat/mustahik/forms.py
+++ b/sizakat/mustahik/forms.py
@@ -55,6 +55,7 @@ class DataSourceInstitusiForm(forms.ModelForm):
             'pic_position',
             'name',
             'province',
+            'regency',
             'sub_district',
             'village',
             'rt',
diff --git a/sizakat/mustahik/migrations/0002_auto_20200816_1347.py b/sizakat/mustahik/migrations/0002_auto_20200816_1347.py
new file mode 100644
index 0000000000000000000000000000000000000000..457c1dfdb18de2d09c3faf91844c818d0b363dd7
--- /dev/null
+++ b/sizakat/mustahik/migrations/0002_auto_20200816_1347.py
@@ -0,0 +1,23 @@
+# Generated by Django 3.0.7 on 2020-08-16 13:47
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('mustahik', '0001_initial'),
+    ]
+
+    operations = [
+        migrations.AlterField(
+            model_name='datasourceinstitusi',
+            name='address',
+            field=models.CharField(blank=True, max_length=255, null=True),
+        ),
+        migrations.AlterField(
+            model_name='datasourceinstitusi',
+            name='pic_position',
+            field=models.CharField(blank=True, max_length=50, null=True),
+        ),
+    ]
diff --git a/sizakat/mustahik/migrations/0003_change_mustahik_photo_to_imagefield.py b/sizakat/mustahik/migrations/0003_change_mustahik_photo_to_imagefield.py
new file mode 100644
index 0000000000000000000000000000000000000000..c5ac8ca905b4b7ff638fc32313c01e21a4a26a32
--- /dev/null
+++ b/sizakat/mustahik/migrations/0003_change_mustahik_photo_to_imagefield.py
@@ -0,0 +1,18 @@
+# Generated by Django 3.0.7 on 2020-09-04 11:39
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('mustahik', '0002_auto_20200816_1347'),
+    ]
+
+    operations = [
+        migrations.AlterField(
+            model_name='mustahik',
+            name='photo',
+            field=models.ImageField(default='images/default_photo.jpg', upload_to='images/mustahik'),
+        ),
+    ]
diff --git a/sizakat/mustahik/models.py b/sizakat/mustahik/models.py
index bf217851a23b10f43ddfbb0d59795bd5db415af6..40932b6e05f8a202b0778765e3c81af719f784d5 100644
--- a/sizakat/mustahik/models.py
+++ b/sizakat/mustahik/models.py
@@ -33,7 +33,7 @@ class Mustahik(models.Model):
     birthdate = models.DateField()
     status = models.CharField(max_length=32, choices=Status.choices)
     gender = models.CharField(max_length=1, choices=Gender.choices)
-    photo = models.FileField(
+    photo = models.ImageField(
         upload_to=os.path.join('images', 'mustahik'),
         default=os.path.join('images', 'default_photo.jpg')
     )
@@ -105,11 +105,12 @@ class DataSourceInstitusi(DataSourceDetail):
     rw = models.CharField(
         max_length=3, validators=[validate_numeric_character]
     )
-    address = models.CharField(max_length=255)
+    address = models.CharField(max_length=255, blank=True, null=True)
     data_source = models.OneToOneField(
         'DataSource', on_delete=models.CASCADE,
         limit_choices_to={'category': DataSource.Category.INSTITUSI}
     )
+    pic_position = models.CharField(max_length=50, blank=True, null=True)
 
 
 class DataSourcePekerja(DataSourceDetail):
diff --git a/sizakat/mustahik/query.py b/sizakat/mustahik/query.py
index 3e989cec27a18102246bbabaf202f0be878c9b45..72667bc32d51d4d67a1eed925cd956094872978c 100644
--- a/sizakat/mustahik/query.py
+++ b/sizakat/mustahik/query.py
@@ -11,26 +11,35 @@ class MustahikQuery(graphene.ObjectType):
     mustahiks = graphene.List(
         MustahikType,
         statuses=graphene.List(graphene.String),
-        name_contains=graphene.String()
+        name_contains=graphene.String(),
+        data_sources=graphene.List(graphene.ID)
     )
     mustahik = graphene.Field(MustahikType, id=graphene.ID(required=True))
     data_sources = graphene.List(
         DataSourceType, category=graphene.String(),
-        name_contains=graphene.String()
+        name_contains=graphene.String(),
+        picName_contains=graphene.String()
     )
     data_source = graphene.Field(DataSourceType, id=graphene.ID(required=True))
 
     def resolve_mustahiks(self, info, **kwargs):
         statuses = kwargs.get('statuses', None)
+        data_sources = kwargs.get('data_sources', None)
         name_contains = kwargs.get('name_contains', None)
         filter_query = Q()
 
         if statuses and len(statuses) > 0:
-            filter_query |= reduce(
+            filter_query &= reduce(
                 lambda a, b: a | b,
                 [Q(status=status) for status in statuses]
             )
 
+        if data_sources and len(data_sources) > 0:
+            filter_query &= reduce(
+                lambda a, b: a | b,
+                [Q(data_source=data_source) for data_source in data_sources]
+            )
+
         if name_contains:
             filter_query &= Q(name__icontains=name_contains)
 
@@ -39,9 +48,13 @@ class MustahikQuery(graphene.ObjectType):
     def resolve_mustahik(self, info, id):
         return Mustahik.objects.get(pk=id)
 
+    def resolve_data_source(self, info, id):
+        return DataSource.objects.get(pk=id)
+
     def resolve_data_sources(self, info, **kwargs):
         category = kwargs.get('category', None)
         query = kwargs.get('name_contains', None)
+        picName = kwargs.get('picName_contains', None)
         filter_query = Q()
         if category:
             filter_query &= Q(category=category)
@@ -56,7 +69,14 @@ class MustahikQuery(graphene.ObjectType):
                 | Q(datasourcewarga__village__icontains=query)
             )
 
+        if picName:
+            filter_query &= (
+                Q(datasourcepekerja__pic_name__icontains=picName)
+                | Q(datasourceinstitusi__pic_name__icontains=picName)
+                | Q(datasourcewarga__pic_name__icontains=picName)
+                
+            )
+
         return DataSource.objects.filter(filter_query)
 
-    def resolve_data_source(self, info, id):
-        return DataSource.objects.get(pk=id)
+
diff --git a/sizakat/mustahik/tests.py b/sizakat/mustahik/tests.py
index 082e828b57810fa527b6b0e41b4e0f8e56b4cad5..f82c5f69f757964a893bf44a7019836191091ffd 100644
--- a/sizakat/mustahik/tests.py
+++ b/sizakat/mustahik/tests.py
@@ -361,6 +361,44 @@ class MustahikGraphQLTestCase(GraphQLTestCase):
         content = json.loads(response.content)
         self.assertEqual(len(content['data']['mustahiks']), 0)
 
+    def test_mustahiks_query_if_data_sources_provided_should_return_mustahiks_with_coresponding_data_sources(self):
+        dataSourceId = DataSource.objects.all()[0].id
+        response = self.query(
+            '''
+            query mustahiks($dataSources: [ID]) {
+                mustahiks(dataSources: $dataSources) {
+                    dataSource {
+                        id
+                    }
+                }
+            }
+            ''',
+            op_name='mustahiks',
+            variables={'dataSources': [dataSourceId]}
+        )
+
+        content = json.loads(response.content)
+        self.assertEqual(int(content['data']['mustahiks'][0]['dataSource']['id']), dataSourceId)
+
+    def test_mustahiks_query_if_data_sources_provided_has_no_corresponding_mustahiks_it_should_return_empty_list(self):
+        dataSourceId = 99999
+        response = self.query(
+            '''
+            query mustahiks($dataSources: [ID]) {
+                mustahiks(dataSources: $dataSources) {
+                    dataSource {
+                        id
+                    }
+                }
+            }
+            ''',
+            op_name='mustahiks',
+            variables={'dataSources': [dataSourceId]}
+        )
+
+        content = json.loads(response.content)
+        self.assertEqual(len(content['data']['mustahiks']), 0)
+
     def test_data_sources_query_should_return_list_data_sources(self):
         response = self.query(
             '''
@@ -479,6 +517,7 @@ class MustahikGraphQLTestCase(GraphQLTestCase):
         self.assertEqual(content['data']['q3']['id'], str(institusi_detail.data_source.pk))
         self.assertEqual(content['data']['q3']['detail']['__typename'], 'DataSourceInstitusiType')
 
+
     def test_data_source_mutation_can_add_new_data_source(self):
         existing_data_source_ammount = DataSource.objects.count()
         response = self.query(
@@ -739,6 +778,7 @@ class MustahikGraphQLTestCase(GraphQLTestCase):
                 "picPosition": "Vice",
                 "name": "Pesantren Yatim",
                 "province": "Jawa Barat",
+                "regency": "Kabupaten",
                 "subDistrict": "Dusun",
                 "village": "desa",
                 "rt": "002",
@@ -803,14 +843,13 @@ class MustahikGraphQLTestCase(GraphQLTestCase):
                 "picKtp": pic_ktp,
                 "picName": new_pic_name,
                 "picPhone": "123456789012",
-                "picPosition": "Head",
                 "name": "Institusi Bandung",
                 "province": "Jawa Barat",
+                "regency": "Kota",
                 "subDistrict": "Bogor",
                 "village": "Desa",
                 "rt": "001",
                 "rw": "001",
-                "address": "Jalan suatu desa no 1",
                 "dataSource": data_source_institusi.pk,
                 "id": source_institusi.pk,
             }
@@ -871,3 +910,38 @@ class MustahikGraphQLTestCase(GraphQLTestCase):
             datasource_warga = datasource['dataSourceDetail']
             kelurahan = datasource_warga.get('village', None)
             self.assertIn(kelurahan, ['pinangranti', None])
+
+    def test_query_search_by_picname(self):
+        response = self.query(
+        '''
+        {
+            dataSources(picNameContains:"pic test") {
+                id
+                category
+                dataSourceDetail {
+                __typename
+                ... on DataSourceInstitusiType {
+                    picName
+                    name
+                }
+                ... on DataSourcePekerjaType {
+                    picName
+                    profession
+                    location
+                }
+                ... on DataSourceWargaType {
+                    picName
+                    rt
+                    rw
+                    village
+                }
+                }
+            }
+        }
+        ''')
+        self.assertResponseNoErrors(response)
+        datasources = json.loads(response.content)['data']['dataSources']
+        for datasource in datasources:
+            datasourceDetails = datasource['dataSourceDetail']
+            picName = datasourceDetails.get('picName', None)
+            self.assertIn(picName, ['pic test', None])
\ No newline at end of file
diff --git a/sizakat/mustahik/types.py b/sizakat/mustahik/types.py
index 2b1a7a25f7fdfd42fc97d2d8b658a5ca0afb66b3..a7e626b03b1d40f232290f8a5796d74f5bab0e1a 100644
--- a/sizakat/mustahik/types.py
+++ b/sizakat/mustahik/types.py
@@ -13,6 +13,9 @@ class MustahikType(DjangoObjectType):
 
     age = graphene.Int(source='calculate_age')
 
+    def resolve_photo(self, info, **kwargs):
+        return self.photo and info.context.build_absolute_uri(self.photo.url)
+
 
 class DataSourceInstitusiType(DjangoObjectType):
     class Meta:
diff --git a/sizakat/settings.py b/sizakat/settings.py
index a3e25ad37cf703ea6f99f07e6d4ff0f3cbddde2d..7b2a30a59c6b9c6fae977081126a51bf42384b1e 100644
--- a/sizakat/settings.py
+++ b/sizakat/settings.py
@@ -141,5 +141,5 @@ USE_TZ = True
 
 STATIC_URL = '/static/'
 STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles')
-MEDIA_URL = '/img/'
-MEDIA_ROOT = os.path.join(BASE_DIR, 'images')
+MEDIA_URL = '/media/'
+MEDIA_ROOT = os.path.join(BASE_DIR, 'mediafiles')