{"id":706,"date":"2024-07-23T11:35:25","date_gmt":"2024-07-23T09:35:25","guid":{"rendered":"https:\/\/www.syntera.ch\/blog\/?p=706"},"modified":"2024-07-23T11:35:25","modified_gmt":"2024-07-23T09:35:25","slug":"django-drf-and-table-historization","status":"publish","type":"post","link":"https:\/\/www.syntera.ch\/blog\/2024\/07\/23\/django-drf-and-table-historization\/","title":{"rendered":"Django DRF and Table Historization"},"content":{"rendered":"\n<div class=\"wp-block-columns is-layout-flex wp-container-core-columns-is-layout-28f84493 wp-block-columns-is-layout-flex\">\n<div class=\"wp-block-column is-vertically-aligned-top is-layout-flow wp-block-column-is-layout-flow\"><div class=\"wp-block-post-author has-medium-font-size\"><div class=\"wp-block-post-author__avatar\"><img alt='' src='https:\/\/secure.gravatar.com\/avatar\/4a88ceaa2d30e0c6f32856b2a56416e928a7b351e59466174227ac639abe522c?s=48&#038;d=mm&#038;r=g' srcset='https:\/\/secure.gravatar.com\/avatar\/4a88ceaa2d30e0c6f32856b2a56416e928a7b351e59466174227ac639abe522c?s=96&#038;d=mm&#038;r=g 2x' class='avatar avatar-48 photo' height='48' width='48' \/><\/div><div class=\"wp-block-post-author__content\"><p class=\"wp-block-post-author__byline\">LEAD DATA SCIENCE<\/p><p class=\"wp-block-post-author__name\">Kail Kuhn Schlicht<\/p><\/div><\/div><\/div>\n\n\n\n<div class=\"wp-block-column is-vertically-aligned-top is-layout-flow wp-block-column-is-layout-flow\">\n<ul class=\"wp-block-outermost-social-sharing alignright has-small-icon-size has-icon-color is-style-logos-only is-content-justification-left is-layout-flex wp-container-outermost-social-sharing-is-layout-fc4fd283 wp-block-outermost-social-sharing-is-layout-flex\"><li style=\"color: #1a4548; \" class=\"outermost-social-sharing-link outermost-social-sharing-link-linkedin has-primary-color wp-block-outermost-social-sharing-link\">\n\t<a href=\"https:\/\/www.linkedin.com\/shareArticle?mini=true&#038;url=https%3A%2F%2Fwww.syntera.ch%2Fblog%2F2024%2F07%2F23%2Fdjango-drf-and-table-historization%2F&#038;title=Django%20DRF%20and%20Table%20Historization\" aria-label=\"Share on LinkedIn\" rel=\"noopener nofollow\" target=\"_blank\" class=\"wp-block-outermost-social-sharing-link-anchor\">\n\t\t<svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" version=\"1.1\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" aria-hidden=\"true\" focusable=\"false\"><path d=\"M19.7,3H4.3C3.582,3,3,3.582,3,4.3v15.4C3,20.418,3.582,21,4.3,21h15.4c0.718,0,1.3-0.582,1.3-1.3V4.3 C21,3.582,20.418,3,19.7,3z M8.339,18.338H5.667v-8.59h2.672V18.338z M7.004,8.574c-0.857,0-1.549-0.694-1.549-1.548 c0-0.855,0.691-1.548,1.549-1.548c0.854,0,1.547,0.694,1.547,1.548C8.551,7.881,7.858,8.574,7.004,8.574z M18.339,18.338h-2.669 v-4.177c0-0.996-0.017-2.278-1.387-2.278c-1.389,0-1.601,1.086-1.601,2.206v4.249h-2.667v-8.59h2.559v1.174h0.037 c0.356-0.675,1.227-1.387,2.526-1.387c2.703,0,3.203,1.779,3.203,4.092V18.338z\"><\/path><\/svg>\t\t<span class=\"wp-block-outermost-social-sharing-link-label screen-reader-text\">\n\t\t\tShare on LinkedIn\t\t<\/span>\n\t<\/a>\n<\/li>\n\n\n<li style=\"color: #1a4548; \" class=\"outermost-social-sharing-link outermost-social-sharing-link-mail has-primary-color wp-block-outermost-social-sharing-link\">\n\t<a href=\"mailto:?subject=Django%20DRF%20and%20Table%20Historization&#038;body=Django%20DRF%20and%20Table%20Historization%20&mdash;%20https%3A%2F%2Fwww.syntera.ch%2Fblog%2F2024%2F07%2F23%2Fdjango-drf-and-table-historization%2F\" aria-label=\"Email this Page\"  class=\"wp-block-outermost-social-sharing-link-anchor\">\n\t\t<svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" version=\"1.1\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" aria-hidden=\"true\" focusable=\"false\"><path d=\"M20,4H4C2.895,4,2,4.895,2,6v12c0,1.105,0.895,2,2,2h16c1.105,0,2-0.895,2-2V6C22,4.895,21.105,4,20,4z M20,8.236l-8,4.882 L4,8.236V6h16V8.236z\"><\/path><\/svg>\t\t<span class=\"wp-block-outermost-social-sharing-link-label screen-reader-text\">\n\t\t\tEmail this Page\t\t<\/span>\n\t<\/a>\n<\/li>\n\n\n<li style=\"color: #1a4548; \" class=\"outermost-social-sharing-link outermost-social-sharing-link-whatsapp has-primary-color wp-block-outermost-social-sharing-link\">\n\t<a href=\"https:\/\/api.whatsapp.com\/send?text=Django%20DRF%20and%20Table%20Historization%20&mdash;%20https%3A%2F%2Fwww.syntera.ch%2Fblog%2F2024%2F07%2F23%2Fdjango-drf-and-table-historization%2F\" aria-label=\"Share on WhatsApp\" rel=\"noopener nofollow\" target=\"_blank\" class=\"wp-block-outermost-social-sharing-link-anchor\">\n\t\t<svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" version=\"1.1\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" aria-hidden=\"true\" focusable=\"false\"><path d=\"M 12.011719 2 C 6.5057187 2 2.0234844 6.478375 2.0214844 11.984375 C 2.0204844 13.744375 2.4814687 15.462563 3.3554688 16.976562 L 2 22 L 7.2324219 20.763672 C 8.6914219 21.559672 10.333859 21.977516 12.005859 21.978516 L 12.009766 21.978516 C 17.514766 21.978516 21.995047 17.499141 21.998047 11.994141 C 22.000047 9.3251406 20.962172 6.8157344 19.076172 4.9277344 C 17.190172 3.0407344 14.683719 2.001 12.011719 2 z M 12.009766 4 C 14.145766 4.001 16.153109 4.8337969 17.662109 6.3417969 C 19.171109 7.8517969 20.000047 9.8581875 19.998047 11.992188 C 19.996047 16.396187 16.413812 19.978516 12.007812 19.978516 C 10.674812 19.977516 9.3544062 19.642812 8.1914062 19.007812 L 7.5175781 18.640625 L 6.7734375 18.816406 L 4.8046875 19.28125 L 5.2851562 17.496094 L 5.5019531 16.695312 L 5.0878906 15.976562 C 4.3898906 14.768562 4.0204844 13.387375 4.0214844 11.984375 C 4.0234844 7.582375 7.6067656 4 12.009766 4 z M 8.4765625 7.375 C 8.3095625 7.375 8.0395469 7.4375 7.8105469 7.6875 C 7.5815469 7.9365 6.9355469 8.5395781 6.9355469 9.7675781 C 6.9355469 10.995578 7.8300781 12.182609 7.9550781 12.349609 C 8.0790781 12.515609 9.68175 15.115234 12.21875 16.115234 C 14.32675 16.946234 14.754891 16.782234 15.212891 16.740234 C 15.670891 16.699234 16.690438 16.137687 16.898438 15.554688 C 17.106437 14.971687 17.106922 14.470187 17.044922 14.367188 C 16.982922 14.263188 16.816406 14.201172 16.566406 14.076172 C 16.317406 13.951172 15.090328 13.348625 14.861328 13.265625 C 14.632328 13.182625 14.464828 13.140625 14.298828 13.390625 C 14.132828 13.640625 13.655766 14.201187 13.509766 14.367188 C 13.363766 14.534188 13.21875 14.556641 12.96875 14.431641 C 12.71875 14.305641 11.914938 14.041406 10.960938 13.191406 C 10.218937 12.530406 9.7182656 11.714844 9.5722656 11.464844 C 9.4272656 11.215844 9.5585938 11.079078 9.6835938 10.955078 C 9.7955938 10.843078 9.9316406 10.663578 10.056641 10.517578 C 10.180641 10.371578 10.223641 10.267562 10.306641 10.101562 C 10.389641 9.9355625 10.347156 9.7890625 10.285156 9.6640625 C 10.223156 9.5390625 9.737625 8.3065 9.515625 7.8125 C 9.328625 7.3975 9.131125 7.3878594 8.953125 7.3808594 C 8.808125 7.3748594 8.6425625 7.375 8.4765625 7.375 z\"><\/path><\/svg>\t\t<span class=\"wp-block-outermost-social-sharing-link-label screen-reader-text\">\n\t\t\tShare on WhatsApp\t\t<\/span>\n\t<\/a>\n<\/li>\n<\/ul>\n<\/div>\n<\/div>\n\n\n\n<h4 class=\"wp-block-heading\">Introduction<\/h4>\n\n\n\n<p>In the age of data-driven decision making, tracking data changes over time is essential. Whether for compliance, data recovery, or trend analysis, table historization is key. This blog post explores how to implement table historization using Django and Django Rest Framework (DRF), a combination that ensures your data is always trackable and audit-ready.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Why Table Historization?<\/h4>\n\n\n\n<p>Table historization isn\u2019t just about recording data changes; it\u2019s about unlocking insights and ensuring accountability. Here\u2019s why it matters:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Enhanced Data Integrity<\/strong>: Ensures data accuracy and consistency.<\/li>\n\n\n\n<li><strong>Auditability<\/strong>: Meets regulatory requirements with clear records of data modifications.<\/li>\n\n\n\n<li><strong>Change Analysis<\/strong>: Helps understand trends and patterns in data.<\/li>\n\n\n\n<li><strong>Data Recovery<\/strong>: Quickly revert to previous data states in case of errors.<\/li>\n<\/ul>\n\n\n\n<h4 class=\"wp-block-heading\">Prerequisites<\/h4>\n\n\n\n<p>Ensure you have a basic understanding of Django and DRF, and the following installed:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Django<\/li>\n\n\n\n<li>Django Rest Framework<\/li>\n\n\n\n<li>Django Simple History<\/li>\n<\/ul>\n\n\n\n<h5 class=\"wp-block-heading\">Hands-on: Setting Up the Project &amp; Installing Django Simple History<\/h5>\n\n\n\n<p>Create a new Django project and app:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>django-admin startproject historization_project\ncd historization_project\ndjango-admin startapp records\npip install django-simple-history\n<\/code><\/pre>\n\n\n\n<p>Add to <code>INSTALLED_APPS<\/code> in <code>settings.py<\/code>:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>INSTALLED_APPS = &#91;<br>'simple_history',<br>'records',<br>'rest_framework',<br>]<\/code><\/pre>\n\n\n\n<h5 class=\"wp-block-heading\">Defining and Migrating Models<\/h5>\n\n\n\n<p>Define a historized model:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># records\/models.py\nfrom django.db import models\nfrom simple_history.models import HistoricalRecords\n\nclass Record(models.Model):\nname = models.CharField(max_length=100)\ndescription = models.TextField()\ncreated_at = models.DateTimeField(auto_now_add=True)\nupdated_at = models.DateTimeField(auto_now=True)\nhistory = HistoricalRecords()<\/code><\/pre>\n\n\n\n<p>Apply migrations:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>python manage.py makemigrations<br>python manage.py migrate<\/code><\/pre>\n\n\n\n<p>Serializing Historical Data<\/p>\n\n\n\n<p>Create serializers for current and historical records:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># records\/serializers.py\nfrom rest_framework import serializers\nfrom .models import Record\n\nclass RecordSerializer(serializers.ModelSerializer):\n    class Meta:\n        model = Record\n        fields = '__all__'\n\nclass HistoricalRecordSerializer(serializers.ModelSerializer):\n    class Meta:\n        model = Record.history.model\n        fields = '__all__'<\/code><\/pre>\n\n\n\n<h5 class=\"wp-block-heading\">Creating Views and URLs<\/h5>\n\n\n\n<p>Create views to handle CRUD operations and retrieve historical data:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># records\/views.py\nfrom rest_framework import viewsets\nfrom .models import Record\nfrom .serializers import RecordSerializer, HistoricalRecordSerializer\nfrom rest_framework.decorators import action\nfrom rest_framework.response import Response\n\nclass RecordViewSet(viewsets.ModelViewSet):\n    queryset = Record.objects.all()\n    serializer_class = RecordSerializer\n\n    @action(detail=True, methods=&#91;'get'])\n    def history(self, request, pk=None):\n        record = self.get_object()\n        history = record.history.all()\n        serializer = HistoricalRecordSerializer(history, many=True)\n        return Response(serializer.data)\n<\/code><\/pre>\n\n\n\n<h5 class=\"wp-block-heading\">Define URLs:<\/h5>\n\n\n\n<pre class=\"wp-block-code\"><code># records\/urls.py\nfrom django.urls import path, include\nfrom rest_framework.routers import DefaultRouter\nfrom .views import RecordViewSet\n\nrouter = DefaultRouter()\nrouter.register(r'records', RecordViewSet)\n\nurlpatterns = &#91;\n    path('', include(router.urls)),\n]\n__\n# historization_project\/urls.py\nfrom django.contrib import admin\nfrom django.urls import path, include\n\nurlpatterns = &#91;\n    path('admin\/', admin.site.urls),\n    path('api\/', include('records.urls')),\n]<\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">Testing Historization<\/h4>\n\n\n\n<h5 class=\"wp-block-heading\">Using the Endpoints in Your Browser<\/h5>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>Creating and Updating Records:<\/strong>\n<ul class=\"wp-block-list\">\n<li>Open your browser and navigate to your API interface, typically something like <code>http:\/\/localhost:8000\/api\/records\/<\/code>.<\/li>\n\n\n\n<li>Use the POST method to add a new record. Input the record details in JSON format and submit.<\/li>\n\n\n\n<li>To update a record, navigate to the specific record&#8217;s URL, e.g., <code>http:\/\/localhost:8000\/api\/records\/1\/<\/code>, switch to the PUT method, and provide the updated details in JSON format.<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>Viewing Historical Data:<\/strong>\n<ul class=\"wp-block-list\">\n<li>In your browser, go to the URL <code>http:\/\/localhost:8000\/api\/records\/1\/history\/<\/code> to see the history of changes for the record with ID 1.<\/li>\n\n\n\n<li>This will display a list of all changes made to the record, including the original creation and any subsequent updates.<\/li>\n<\/ul>\n<\/li>\n<\/ol>\n\n\n\n<h4 class=\"wp-block-heading\">Conclusion<\/h4>\n\n\n\n<p>Implementing table historization in Django using Django Simple History and DRF is straightforward and highly beneficial. With just a few configurations, you can set up a robust system that tracks every change to your data. This setup provides enhanced data integrity, compliance with regulatory requirements, the ability to perform change analysis, and easy data recovery.<\/p>\n\n\n\n<p>The benefits of this approach include:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Ease of Setup<\/strong>: Minimal configuration is required to get started, making it accessible even for those new to Django.<\/li>\n\n\n\n<li><strong>Comprehensive Tracking<\/strong>: Automatically tracks all changes, providing a complete audit trail.<\/li>\n\n\n\n<li><strong>Enhanced Data Insights<\/strong>: Enables historical data analysis, helping to uncover trends and patterns.<\/li>\n\n\n\n<li><strong>Improved Compliance<\/strong>: Meets auditing and compliance standards effortlessly.<\/li>\n\n\n\n<li><strong>Reliable Data Recovery<\/strong>: Allows easy rollback to previous data states, safeguarding against accidental changes or data loss.<\/li>\n<\/ul>\n\n\n\n<p>Whether you&#8217;re in finance, healthcare, legal services, or any other industry that requires rigorous data tracking and compliance, table historization offers a powerful solution.<\/p>\n\n\n\n<p>If you have any questions or would like to discuss this topic further, feel free to reach out to me. I&#8217;m always happy to help!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Introduction In the age of data-driven decision making, tracking data changes over time is essential. Whether for compliance, data recovery, or trend analysis, table historization is key. This blog post explores how to implement table historization using Django and Django Rest Framework (DRF), a combination that ensures your data is always trackable and audit-ready. Why [&hellip;]<\/p>\n","protected":false},"author":5,"featured_media":718,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[14,48],"tags":[],"class_list":["post-706","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-data-science","category-django"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v21.8 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Django DRF and Table Historization - Syntera<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.syntera.ch\/blog\/2024\/07\/23\/django-drf-and-table-historization\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Django DRF and Table Historization - Syntera\" \/>\n<meta property=\"og:description\" content=\"Introduction In the age of data-driven decision making, tracking data changes over time is essential. Whether for compliance, data recovery, or trend analysis, table historization is key. This blog post explores how to implement table historization using Django and Django Rest Framework (DRF), a combination that ensures your data is always trackable and audit-ready. Why [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.syntera.ch\/blog\/2024\/07\/23\/django-drf-and-table-historization\/\" \/>\n<meta property=\"og:site_name\" content=\"Syntera\" \/>\n<meta property=\"article:published_time\" content=\"2024-07-23T09:35:25+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.syntera.ch\/blog\/wp-content\/uploads\/2024\/07\/dajngo.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"820\" \/>\n\t<meta property=\"og:image:height\" content=\"461\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"Kail Kuhn Schlicht\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Kail Kuhn Schlicht\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"3 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.syntera.ch\/blog\/2024\/07\/23\/django-drf-and-table-historization\/\",\"url\":\"https:\/\/www.syntera.ch\/blog\/2024\/07\/23\/django-drf-and-table-historization\/\",\"name\":\"Django DRF and Table Historization - Syntera\",\"isPartOf\":{\"@id\":\"https:\/\/www.syntera.ch\/blog\/#website\"},\"datePublished\":\"2024-07-23T09:35:25+00:00\",\"dateModified\":\"2024-07-23T09:35:25+00:00\",\"author\":{\"@id\":\"https:\/\/www.syntera.ch\/blog\/#\/schema\/person\/8048dfb9e4b2f044222a4baa11ee3e68\"},\"breadcrumb\":{\"@id\":\"https:\/\/www.syntera.ch\/blog\/2024\/07\/23\/django-drf-and-table-historization\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.syntera.ch\/blog\/2024\/07\/23\/django-drf-and-table-historization\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.syntera.ch\/blog\/2024\/07\/23\/django-drf-and-table-historization\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/www.syntera.ch\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Django DRF and Table Historization\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.syntera.ch\/blog\/#website\",\"url\":\"https:\/\/www.syntera.ch\/blog\/\",\"name\":\"Syntera\",\"description\":\"translating data into business value.\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/www.syntera.ch\/blog\/?s={search_term_string}\"},\"query-input\":\"required name=search_term_string\"}],\"inLanguage\":\"en-US\"},{\"@type\":\"Person\",\"@id\":\"https:\/\/www.syntera.ch\/blog\/#\/schema\/person\/8048dfb9e4b2f044222a4baa11ee3e68\",\"name\":\"Kail Kuhn Schlicht\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.syntera.ch\/blog\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/4a88ceaa2d30e0c6f32856b2a56416e928a7b351e59466174227ac639abe522c?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/4a88ceaa2d30e0c6f32856b2a56416e928a7b351e59466174227ac639abe522c?s=96&d=mm&r=g\",\"caption\":\"Kail Kuhn Schlicht\"},\"sameAs\":[\"https:\/\/www.linkedin.com\/in\/kail-kuhn-schlicht-603584a3\/\"],\"url\":\"https:\/\/www.syntera.ch\/blog\/author\/kail\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Django DRF and Table Historization - Syntera","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.syntera.ch\/blog\/2024\/07\/23\/django-drf-and-table-historization\/","og_locale":"en_US","og_type":"article","og_title":"Django DRF and Table Historization - Syntera","og_description":"Introduction In the age of data-driven decision making, tracking data changes over time is essential. Whether for compliance, data recovery, or trend analysis, table historization is key. This blog post explores how to implement table historization using Django and Django Rest Framework (DRF), a combination that ensures your data is always trackable and audit-ready. Why [&hellip;]","og_url":"https:\/\/www.syntera.ch\/blog\/2024\/07\/23\/django-drf-and-table-historization\/","og_site_name":"Syntera","article_published_time":"2024-07-23T09:35:25+00:00","og_image":[{"width":820,"height":461,"url":"https:\/\/www.syntera.ch\/blog\/wp-content\/uploads\/2024\/07\/dajngo.jpg","type":"image\/jpeg"}],"author":"Kail Kuhn Schlicht","twitter_card":"summary_large_image","twitter_misc":{"Written by":"Kail Kuhn Schlicht","Est. reading time":"3 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/www.syntera.ch\/blog\/2024\/07\/23\/django-drf-and-table-historization\/","url":"https:\/\/www.syntera.ch\/blog\/2024\/07\/23\/django-drf-and-table-historization\/","name":"Django DRF and Table Historization - Syntera","isPartOf":{"@id":"https:\/\/www.syntera.ch\/blog\/#website"},"datePublished":"2024-07-23T09:35:25+00:00","dateModified":"2024-07-23T09:35:25+00:00","author":{"@id":"https:\/\/www.syntera.ch\/blog\/#\/schema\/person\/8048dfb9e4b2f044222a4baa11ee3e68"},"breadcrumb":{"@id":"https:\/\/www.syntera.ch\/blog\/2024\/07\/23\/django-drf-and-table-historization\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.syntera.ch\/blog\/2024\/07\/23\/django-drf-and-table-historization\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/www.syntera.ch\/blog\/2024\/07\/23\/django-drf-and-table-historization\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.syntera.ch\/blog\/"},{"@type":"ListItem","position":2,"name":"Django DRF and Table Historization"}]},{"@type":"WebSite","@id":"https:\/\/www.syntera.ch\/blog\/#website","url":"https:\/\/www.syntera.ch\/blog\/","name":"Syntera","description":"translating data into business value.","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.syntera.ch\/blog\/?s={search_term_string}"},"query-input":"required name=search_term_string"}],"inLanguage":"en-US"},{"@type":"Person","@id":"https:\/\/www.syntera.ch\/blog\/#\/schema\/person\/8048dfb9e4b2f044222a4baa11ee3e68","name":"Kail Kuhn Schlicht","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.syntera.ch\/blog\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/4a88ceaa2d30e0c6f32856b2a56416e928a7b351e59466174227ac639abe522c?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/4a88ceaa2d30e0c6f32856b2a56416e928a7b351e59466174227ac639abe522c?s=96&d=mm&r=g","caption":"Kail Kuhn Schlicht"},"sameAs":["https:\/\/www.linkedin.com\/in\/kail-kuhn-schlicht-603584a3\/"],"url":"https:\/\/www.syntera.ch\/blog\/author\/kail\/"}]}},"_links":{"self":[{"href":"https:\/\/www.syntera.ch\/blog\/wp-json\/wp\/v2\/posts\/706","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.syntera.ch\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.syntera.ch\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.syntera.ch\/blog\/wp-json\/wp\/v2\/users\/5"}],"replies":[{"embeddable":true,"href":"https:\/\/www.syntera.ch\/blog\/wp-json\/wp\/v2\/comments?post=706"}],"version-history":[{"count":4,"href":"https:\/\/www.syntera.ch\/blog\/wp-json\/wp\/v2\/posts\/706\/revisions"}],"predecessor-version":[{"id":719,"href":"https:\/\/www.syntera.ch\/blog\/wp-json\/wp\/v2\/posts\/706\/revisions\/719"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.syntera.ch\/blog\/wp-json\/wp\/v2\/media\/718"}],"wp:attachment":[{"href":"https:\/\/www.syntera.ch\/blog\/wp-json\/wp\/v2\/media?parent=706"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.syntera.ch\/blog\/wp-json\/wp\/v2\/categories?post=706"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.syntera.ch\/blog\/wp-json\/wp\/v2\/tags?post=706"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}