Getting Started#
This guide walks you through your first FairDM experience: running a demo portal, defining your first custom Sample and Measurement models, and seeing them come to life in both the UI and via the API.
Note
Prerequisites: Before starting, ensure you’ve reviewed Before You Begin and have Python 3.13+, Poetry, and Git installed.
What You’ll Build#
By the end of this guide, you will have:
A working FairDM demo portal running locally
A custom
RockSamplemodel with domain-specific fieldsA custom
MineralAnalysismeasurement modelBoth models registered with FairDM and visible in the portal UI
Programmatic access to your models via the API
Step 1: Run the Demo Portal#
The fastest way to explore FairDM is to run the included demo portal. This portal comes pre-configured with example data and demonstrates all core features.
Clone the Repository#
git clone https://github.com/FAIR-DM/fairdm.git
cd fairdm
Install Dependencies#
poetry install
Set Up the Database#
poetry run python manage.py migrate
poetry run python manage.py loaddata fairdm/fixtures/demo.json.bz2
Start the Development Server#
poetry run python manage.py runserver
Access the Portal#
Open your browser and navigate to:
http://127.0.0.1:8000
You should see the FairDM demo portal homepage. Take a moment to explore:
Browse existing Projects and Datasets
View Samples and Measurements
Click into detail pages to see the metadata structure
Tip
The demo includes a test user account. Check the demo fixture or create a new superuser with: poetry run python manage.py createsuperuser
Step 2: Define Your First Custom Sample Model#
Now that you have the demo running, let’s create a domain-specific Sample model. We’ll create a RockSample model for geological research.
Create a Custom App#
In a real FairDM project (generated from the cookiecutter), you would create custom models in your own Django app. For this tutorial, we’ll create a simple example in the fairdm_demo app.
Create a new file: fairdm_demo/models/samples.py
from django.db import models
from fairdm.samples.models import Sample
class RockSample(Sample):
"""
A geological rock sample with domain-specific fields.
"""
# Geological properties
rock_type = models.CharField(
max_length=100,
help_text="Type of rock (e.g., igneous, sedimentary, metamorphic)"
)
mineral_composition = models.TextField(
help_text="Primary minerals present in the sample",
blank=True
)
collection_depth_m = models.DecimalField(
max_digits=10,
decimal_places=2,
null=True,
blank=True,
help_text="Depth in meters at which the sample was collected"
)
class Meta:
verbose_name = "Rock Sample"
verbose_name_plural = "Rock Samples"
def __str__(self):
return f"{self.sample_id}: {self.rock_type}"
Key Points#
Extend
Sample: Your custom model inherits fromfairdm.samples.models.Sample, which provides core fields likesample_id,name,description, and FAIR metadataAdd domain fields: Define fields specific to your research domain
Use Django conventions: Standard Django model patterns apply
Step 3: Define a Custom Measurement Model#
Measurements represent observations or analyses performed on samples. Let’s create a MineralAnalysis measurement model.
Create a new file: fairdm_demo/models/measurements.py
from django.db import models
from fairdm.measurements.models import Measurement
class MineralAnalysis(Measurement):
"""
A mineral composition analysis measurement.
"""
analysis_method = models.CharField(
max_length=200,
help_text="Method used for analysis (e.g., X-ray diffraction, mass spectrometry)"
)
mineral_name = models.CharField(
max_length=100,
help_text="Name of the mineral analyzed"
)
percentage_composition = models.DecimalField(
max_digits=5,
decimal_places=2,
help_text="Percentage of this mineral in the sample"
)
detection_limit = models.DecimalField(
max_digits=5,
decimal_places=3,
null=True,
blank=True,
help_text="Detection limit of the analysis method (percentage)"
)
class Meta:
verbose_name = "Mineral Analysis"
verbose_name_plural = "Mineral Analyses"
def __str__(self):
return f"{self.mineral_name} analysis: {self.percentage_composition}%"
Step 4: Register Your Models with FairDM#
To make your models visible in the FairDM UI and API, you need to register them with the FairDM registry. This auto-generates forms, tables, filters, and serializers.
Create a new file: fairdm_demo/registry.py
from fairdm.registry import registry, SampleConfig, MeasurementConfig
from .models.samples import RockSample
from .models.measurements import MineralAnalysis
# Register the RockSample model
registry.register(
RockSample,
config=SampleConfig(
list_display=['sample_id', 'rock_type', 'collection_depth_m', 'created'],
search_fields=['sample_id', 'name', 'rock_type'],
list_filter=['rock_type', 'created'],
)
)
# Register the MineralAnalysis model
registry.register(
MineralAnalysis,
config=MeasurementConfig(
list_display=['mineral_name', 'percentage_composition', 'analysis_method', 'created'],
search_fields=['mineral_name', 'analysis_method'],
list_filter=['mineral_name', 'analysis_method', 'created'],
)
)
Import Your Registry#
Ensure your registry is imported when Django starts. Add to fairdm_demo/apps.py:
from django.apps import AppConfig
class FairdmDemoConfig(AppConfig):
default_auto_field = 'django.db.models.BigAutoField'
name = 'fairdm_demo'
def ready(self):
# Import registry to ensure models are registered
import fairdm_demo.registry # noqa
Step 5: Create and Apply Migrations#
Now that you’ve defined your models, create Django migrations:
poetry run python manage.py makemigrations
poetry run python manage.py migrate
Step 6: Verify in the UI#
Access the Admin Interface#
Navigate to:
http://127.0.0.1:8000/admin/
Log in with your superuser credentials. You should see:
Rock Samples section with options to add/edit rock samples
Mineral Analyses section with options to add/edit measurements
Create a Test Rock Sample#
Click “Add Rock Sample”
Fill in required fields:
Sample ID:
ROCK-001Name:
Basalt from Mt. ExampleRock type:
IgneousMineral composition:
Olivine, pyroxene, plagioclaseCollection depth:
15.50meters
Click “Save”
Create a Test Measurement#
Click “Add Mineral Analysis”
Associate it with your rock sample
Fill in:
Mineral name:
OlivinePercentage composition:
45.00%Analysis method:
X-ray diffraction
Click “Save”
Browse in the Portal#
Navigate back to the main portal:
http://127.0.0.1:8000/samples/
You should see your new ROCK-001 sample listed. Click on it to view the detail page, which will show:
All standard Sample metadata
Your custom fields (rock type, mineral composition, collection depth)
Associated measurements
Step 7: Verify Programmatic Access#
FairDM automatically generates a REST API for registered models. Let’s confirm your models are accessible programmatically.
Using the Browsable API#
Navigate to:
http://127.0.0.1:8000/api/samples/
You should see a JSON response listing all samples, including your RockSample. The API is browsable - you can click links and navigate the data structure.
Using curl#
From your terminal:
curl http://127.0.0.1:8000/api/samples/
You should see JSON output including your custom fields:
{
"count": 1,
"results": [
{
"id": "...",
"sample_id": "ROCK-001",
"name": "Basalt from Mt. Example",
"rock_type": "Igneous",
"mineral_composition": "Olivine, pyroxene, plagioclase",
"collection_depth_m": "15.50",
...
}
]
}
Using Python#
You can also access the API programmatically:
import requests
response = requests.get('http://127.0.0.1:8000/api/samples/')
data = response.json()
for sample in data['results']:
print(f"Sample: {sample['sample_id']} - {sample['name']}")
print(f" Rock type: {sample.get('rock_type', 'N/A')}")
What You’ve Accomplished#
Congratulations! You’ve completed your first FairDM journey:
✅ Ran a local FairDM demo portal
✅ Defined a custom RockSample model with domain-specific fields
✅ Defined a custom MineralAnalysis measurement model
✅ Registered both models with the FairDM registry
✅ Created test data and verified it appears in the UI
✅ Confirmed programmatic access via the REST API
Next Steps#
Now that you understand the basics, explore:
Defining Models: Learn more about Sample and Measurement model patterns
Model Configuration: Customize auto-generated forms, tables, and filters
Using the Registry: Deep dive into registration options
Deployment: Deploy your portal to production
See also
For more advanced topics like custom views, plugins, and integration with external services, see the How-to Guides section.