{"id":608,"date":"2018-02-28T21:08:00","date_gmt":"2018-02-28T21:08:00","guid":{"rendered":"https:\/\/codenerix.com\/?p=608\/"},"modified":"2023-04-06T07:06:54","modified_gmt":"2023-04-06T07:06:54","slug":"codenerixmodel","status":"publish","type":"post","link":"https:\/\/codenerix.com\/en\/codenerixmodel\/","title":{"rendered":"CodenerixModel"},"content":{"rendered":"\n<p>\ud83c\uddea\ud83c\udde6&nbsp;Leer en Espa\u00f1ol, \u201c<a href=\"https:\/\/www.juanmitaboada.com\/codenerix-codenerixmodel\/\">CodenerixModel<\/a>\u201c<\/p>\n\n\n\n<p>For any Django project to support CODENERIX properly, it is necessary to take some important steps to ensure a good start to the project. We will not repeat that using the <a href=\"https:\/\/github.com\/codenerix\/django-codenerix-examples\" target=\"_blank\" rel=\"noreferrer noopener\"><strong><span style=\"color: #343433;\">CODE<\/span><span style=\"color: #70a8e0;\">NERIX<\/span><\/strong> Examples<\/a> available on <a href=\"https:\/\/github.com\/codenerix\/django-codenerix-examples\">GitHub<\/a> is the easiest way to get started.<\/p>\n\n\n\n<p>That is why this time, we will focus on the CORE \/ KERNEL of <strong><a href=\"https:\/\/github.com\/codenerix\/django-codenerix\"><span style=\"color: #343433;\">CODE<\/span><span style=\"color: #70a8e0;\">NERIX<\/span><\/a>, which<\/strong> we will know from now on as <strong>CodenerixModel<\/strong>.<\/p>\n\n\n\n<p><strong>CodenerixModel<\/strong> is an extended class from <strong>Django&#8217;s models.Model <\/strong>where a series of new functionalities are contemplated that we will explain below. First, we must bear in mind that most of the functionalities we will see in <strong><a href=\"https:\/\/github.com\/codenerix\/django-codenerix\"><span style=\"color: #343433;\">CODE<\/span><span style=\"color: #70a8e0;\">NERIX<\/span><\/a><\/strong> are achieved through the use of direct inheritance of classes of this framework. To do this, we are going to see a simple example of a class developed with <strong><a href=\"https:\/\/github.com\/codenerix\/django-codenerix\"><span style=\"color: #343433;\">CODE<\/span><span style=\"color: #70a8e0;\">NERIX<\/span><\/a><\/strong>:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">from codenerix.models import CodenerixModel\n\nfrom django.db import models\n\nclass Author(CodenerixModel):\n    name = models.CharField(_(u'Name'), max_length=128, blank=False, null=False)\n    birth_date = models.CharField(_(u'Birth Date'), max_length=128, blank=False, null=False)\n    def __fields__(self, info):\n        fields=[]\n        fields.append(('name', _('Name'), 100, 'left'))\n        fields.append(('birth_date', _('Birth Date')))\n        return fields<\/pre>\n\n\n\n<p>In this example, we see several things that stand out to us compared to a normal declaration of a model in Django:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>We import <strong>CodenerixModel<\/strong> with:<br><code><code data-enlighter-language=\"python\" class=\"EnlighterJSRAW\">from codenerix.models import CodenerixModel<\/code><\/code><br><br><\/li>\n\n\n\n<li>The model inherits CodenerixModel (not from <strong>models.Model<\/strong>):<br><code><code data-enlighter-language=\"python\" class=\"EnlighterJSRAW\">class Author(CoderixModel):<\/code><\/code><br><br><\/li>\n\n\n\n<li>There is a special method that <strong><mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-vivid-red-color\">is required<\/mark><\/strong> called <strong>__fields__<\/strong> and takes an &#8220;<strong>info<\/strong>&#8221; argument:<br><code><code data-enlighter-language=\"python\" class=\"EnlighterJSRAW\">def fields(self, info):<\/code><\/code><br><br>We must remember that this method must be defined in all the classes inherited from <strong>CodenerixModel<\/strong> since <strong><a href=\"https:\/\/github.com\/codenerix\/django-codenerix\"><span style=\"color: #343433;\">CODE<\/span><span style=\"color: #70a8e0;\">NERIX<\/span><\/a><\/strong> uses it to know how to show the information to the end-user of the application in such a way that it is clear, simple, and usable.<br><\/li>\n\n\n\n<li>The rest of the information in the class is simple to understand and responds to the general paradigm that <strong>Django<\/strong> uses. In fact, <strong><a href=\"https:\/\/github.com\/codenerix\/django-codenerix\"><span style=\"color: #343433;\">CODE<\/span><span style=\"color: #70a8e0;\">NERIX<\/span><\/a><\/strong> always inherits <strong>Django<\/strong> and passes its management to it, thus always ensuring that any improvements to <strong>Django<\/strong> are also available in <strong><a href=\"https:\/\/github.com\/codenerix\/django-codenerix\"><span style=\"color: #343433;\">CODE<\/span><span style=\"color: #70a8e0;\">NERIX<\/span><\/a><\/strong>.<\/li>\n<\/ol>\n\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">What does the <em>__fields__<\/em> method contain?<\/h2>\n\n\n\n<p>It collects what information from the model is useful to be shown when the user wants to work with that model. This method is usually called from lists since the fields that appear here will be used as columns in the listing.<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">def __fields__(self, info):\n    fields=[]\n    fields.append(('name', ('Name'), 100, 'left')) fields.append(('birth_date', ('Birth Date')))\n    return fields<\/pre>\n\n\n\n<p><strong>\u26a0 IMPORTANT: This method is <mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-vivid-red-color\">mandatory<\/mark> in all models inherited from CodenerixModel.<\/strong><\/p>\n\n\n\n<p>The method receives an &#8220;<strong>info<\/strong>&#8221; argument that contains information about the query received (request), including, among other data, the user who makes it and other important meta information for decision-making that will be made within <strong>__fields__<\/strong>. This example is linear, but we can take advantage of this information to detect a user&#8217;s level of access and display some fields or others in the list, adapting the content of the list depending on the user or the system conditions.<\/p>\n\n\n\n<p>This method is expected to respond with a list of tuples containing at least 2 elements. The first will be the field&#8217;s name according to Django&#8217;s model, and the second will be the translatable name of the field to be shown to the user in the column&#8217;s title referenced by that field.<\/p>\n\n\n\n<p>Each tuple, therefore, consists of 2 mandatory elements and several optional elements:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong><mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-luminous-vivid-orange-color\">Required:<\/mark><\/strong> Model field name<\/li>\n\n\n\n<li><strong><mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-luminous-vivid-orange-color\">Required:<\/mark><\/strong> Translatable name of the field to be displayed to the user (it can be None to prevent <strong>Django<\/strong> from rendering that column so that we can receive this field in the <strong>JSON<\/strong> response of the list but without being displayed visually. It is very useful when you want to compose several fields into one)<\/li>\n\n\n\n<li><strong><mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-vivid-cyan-blue-color\">Optional:<\/mark><\/strong> Length of field width in pixels (<mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-vivid-red-color\">deprecated<\/mark>)<\/li>\n\n\n\n<li><strong><mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-vivid-cyan-blue-color\">Optional:<\/mark><\/strong> Alignment of the text within the field (Ex: &#8216;<strong>centre<\/strong>&#8216;)<\/li>\n\n\n\n<li><mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-vivid-cyan-blue-color\"><strong>Optional:<\/strong><\/mark> Name of the filter to apply to the field (Ex: &#8216;<strong>skype<\/strong>&#8216;, which will add the necessary information so that the output of the field is a clickable phone number)<\/li>\n<\/ul>\n\n\n\n<p>3 other special methods provide different functionalities to the models. These are <em>__limitQ__<\/em>, <em>__searchF__,<\/em> and <em>__searchQ__<\/em>.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">What is the <em>__limitQ__<\/em> method?<\/h2>\n\n\n\n<p>It is a <strong>limiting<\/strong> method. Its objective is to limit the results to which the user has access. In this way, __limitQ__ allows you to control the result returned to the user based on the query environment so that if you are a user without privileges, you will not be able to see certain records because a filter will be applied. It is very useful when working with <strong>Roles<\/strong> since it allows you to control the records the user sees based on their role.<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">def __limitQ__(self, info):\n    limits = {}\n    if not info.user.is_admin:\n        criterias = []\n        criterias.append(Q(model__pk=pk_condition))\n        criterias.append(Q(model__field1=condition))\n        limits['profile_people_limit'] = reduce(operator.or_, criterias)\n    return limits<\/pre>\n\n\n\n<p>The method expects to return a dictionary where the key indicates the line to operate on (in case an error occurs while processing the lookup), and the value, on the other hand, is a Django&#8217;s QObject. The QObject will be injected in the Queryset of the list when it is requested, applying or not the filter, depending on the query.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">What is the <em>__searchQ__<\/em> method?<\/h2>\n\n\n\n<p>It is the method used to filter the queries with the text entered in the listings&#8217; upper box. In this way, everything that the user writes in the search box will arrive in the &#8220;<strong>text<\/strong>&#8221; variable, allowing filtering of the search with this text.<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">def __searchQ__(self, info, text):\n    text_filters = {}\n    text_filters['identifier1'] = Q(CharField1__icontains=text)\n    text_filters['identifier2'] = Q(TextField1__icontains=text)\n    text_filters['identifier3'] = Q(IntegerField=34)\n\n    #If text have this a especific word can return another Q condition\n    if text.find(u'magic') != -1:\n        text_filters['identifier4'] = Q(identifier=34)\n\n    return text_filters<\/pre>\n\n\n\n<p>The method expects to return a dictionary where the key indicates the line to operate on (in case an error occurs while processing the lookup), and the value, on the other hand, is a Django&#8217;s QObject. The QObject will be injected in the Queryset of the list when it is requested, applying or not the filter, depending on the query.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">What is the <em>__searchF__<\/em> method?<\/h2>\n\n\n\n<p>It is in charge of displaying the search filters and is used when we want filters to be displayed that facilitate the search. Specifically, its use refers to the personalized definition of these filters, for example, a selector that shows &#8220;A&#8221;, &#8220;M&#8221;, and &#8220;S&#8221; in such a way that if you press &#8220;A&#8221;, you will search for everything that begins with &#8220;A&#8221;, idem for M and S. Still, you will not be able to search for other letters. It is very useful to build combined searches, such as &#8220;give me those of type A&#8221; (green and purple together). It is also used to generate complex filters. CODENERIX automatically includes filters in all the fields of a list with which it knows how to operate natively so that filters will appear for text fields, numeric fields, BooleanFields, ChoiceFields, and dates.<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">def __searchF__(self, info):\n    list1 = []\n    for l1 in Model.objects.all():\n        list1.append((l1.id, l1.field1 + ' ' + l1.field2))\n\n    list2 = []\n    for li in Model2.objects.all():\n        list2.append((li.id, str(li.field)))\n\n    text_filters = {}\n    text_filters['field1'] = (_('Field1'), lambda x: Q(field1__startswith=x), [('h', _('Starts with h')), ('S', _('Starts with S'))])\n    text_filters['field2'] = (_('Field2'), lambda x: Q(field2__pk=x), list1)\n    text_filters['external'] = (_('Field3'), lambda x: Q(pk=x),list2)\n\n    return text_filters<\/pre>\n\n\n\n<p>The method expects to return a dictionary where the <strong>key<\/strong> indicates the filter&#8217;s name. If the name of the filter matches a field in the list, then the filter will be shown in the hidden row below the list&#8217;s title, which is displayed with the icon &#8220;\u2261&#8221;. Otherwise, it will be displayed as an external filter.<\/p>\n\n\n\n<p>The value of the key must be a tuple with 3 elements:<\/p>\n\n\n\n<p><code data-enlighter-language=\"python\" class=\"EnlighterJSRAW\">(('Field1'), lambda x: Q(field1__startswith=x), [('h', ('Starts with h')), ('S', _('Starts with S'))])<\/code><\/p>\n\n\n\n<p>&#8230;in such a way that the first element will be the name of the filter in translatable format, the second a lambda function that receives the value of the filter and returns a <strong>QObject<\/strong> that helps the filter to perform as expected, and the third element should be a list of options to display in the filter. The <strong>QObject<\/strong> returned by the lambda function will be injected into the <strong>Queryset<\/strong> of the list when it is requested, applying or not the filter, depending on the query.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">How do CodenerixModel and GenList interact?<\/h2>\n\n\n\n<p>Although later we will talk about GenList (view used to build lists), we must say that __fields__, __limitQ__, __searchQ__ and __searchF__ are methods that can appear indistinctly in the model and the view of a list. Here&#8217;s how filters interact when a model specifies a filter and a listing doesn&#8217;t, or vice versa.<\/p>\n\n\n\n<p>The following 3 tables show 3 columns:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>The <strong>first<\/strong> indicates if the method is defined in <mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-vivid-cyan-blue-color\"><mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-vivid-cyan-blue-color\"><strong><strong><a href=\"https:\/\/codenerix.com\/en\/codenerixmodel\/\">CodenerixModel<\/a><\/strong><\/strong><\/mark><\/mark>.<\/li>\n\n\n\n<li>The <strong>second<\/strong> indicates if it is defined in <mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-vivid-cyan-blue-color\"><mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-vivid-cyan-blue-color\"><a href=\"https:\/\/codenerix.com\/en\/genlist\/\"><strong>GenList<\/strong><\/a><\/mark><\/mark>.<\/li>\n\n\n\n<li>The <strong>third<\/strong> column indicates the result of applying these filters.<\/li>\n<\/ul>\n\n\n\n<p><\/p>\n\n\n\n<figure class=\"wp-block-table\"><table><thead><tr><td class=\"has-text-align-center\" data-align=\"center\"><strong>__fields__<\/strong><\/td><\/tr><tr><td class=\"has-text-align-center\" data-align=\"center\"><strong><mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-vivid-cyan-blue-color\">CodenerixModel<\/mark><\/strong><\/td><td class=\"has-text-align-center\" data-align=\"center\"><strong><mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-vivid-cyan-blue-color\">GenList<\/mark><\/strong><\/td><td><strong>Applicable<\/strong><\/td><\/tr><\/thead><tbody><tr><td class=\"has-text-align-center\" data-align=\"center\"><mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-vivid-red-color\">NO<\/mark><\/td><td class=\"has-text-align-center\" data-align=\"center\"><mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-vivid-red-color\">NO<\/mark><\/td><td><strong><mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-vivid-red-color\">\u2014 ERROR \u2014<\/mark><\/strong><\/td><\/tr><tr><td class=\"has-text-align-center\" data-align=\"center\"><mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-vivid-red-color\">NO<\/mark><\/td><td class=\"has-text-align-center\" data-align=\"center\"><mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-vivid-green-cyan-color\">YES<\/mark><\/td><td><strong><mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-vivid-red-color\">\u2014 ERROR \u2014<\/mark><\/strong><\/td><\/tr><tr><td class=\"has-text-align-center\" data-align=\"center\"><mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-vivid-green-cyan-color\">YES<\/mark><\/td><td class=\"has-text-align-center\" data-align=\"center\"><mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-vivid-red-color\">NO<\/mark><\/td><td><mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-vivid-cyan-blue-color\">CodenerixModel<\/mark><\/td><\/tr><tr><td class=\"has-text-align-center\" data-align=\"center\"><mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-vivid-green-cyan-color\">YES<\/mark><\/td><td class=\"has-text-align-center\" data-align=\"center\"><mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-vivid-green-cyan-color\">YES<\/mark><\/td><td><mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-vivid-cyan-blue-color\">GenList<\/mark><\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<figure class=\"wp-block-table\"><table><thead><tr><td class=\"has-text-align-center\" data-align=\"center\"><strong>__limitQ__<\/strong><\/td><\/tr><tr><td class=\"has-text-align-center\" data-align=\"center\"><strong><strong><mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-vivid-cyan-blue-color\">CodenerixModel<\/mark><\/strong><\/strong><\/td><td class=\"has-text-align-center\" data-align=\"center\"><strong><strong><mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-vivid-cyan-blue-color\">GenList<\/mark><\/strong><\/strong><\/td><td><strong><strong>Applicable<\/strong><\/strong><\/td><\/tr><\/thead><tbody><tr><td class=\"has-text-align-center\" data-align=\"center\"><mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-vivid-red-color\">NO<\/mark><\/td><td class=\"has-text-align-center\" data-align=\"center\"><mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-vivid-red-color\">NO<\/mark><\/td><td>No filter is applied<\/td><\/tr><tr><td class=\"has-text-align-center\" data-align=\"center\"><mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-vivid-red-color\">NO<\/mark><\/td><td class=\"has-text-align-center\" data-align=\"center\"><mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-vivid-green-cyan-color\">YES<\/mark><\/td><td><strong><strong><strong><mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-vivid-cyan-blue-color\">GenList<\/mark><\/strong><\/strong><\/strong> filter is applied<\/td><\/tr><tr><td class=\"has-text-align-center\" data-align=\"center\"><mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-vivid-green-cyan-color\">YES<\/mark><\/td><td class=\"has-text-align-center\" data-align=\"center\"><mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-vivid-red-color\">NO<\/mark><\/td><td><strong><strong><mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-vivid-cyan-blue-color\">CodenerixModel<\/mark><\/strong><\/strong> filter is applied<\/td><\/tr><tr><td class=\"has-text-align-center\" data-align=\"center\"><mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-vivid-green-cyan-color\">YES<\/mark><\/td><td class=\"has-text-align-center\" data-align=\"center\"><mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-vivid-green-cyan-color\">YES<\/mark><\/td><td><strong><strong><strong><mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-vivid-cyan-blue-color\">GenList<\/mark><\/strong><\/strong><\/strong>&nbsp;and <strong><strong><mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-vivid-cyan-blue-color\">CodenerixModel<\/mark><\/strong><\/strong>&nbsp;filters<br>are applied to put them together<br>with the logic operator \u201c<strong><mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-vivid-purple-color\">AND<\/mark><\/strong>\u201c.<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<figure class=\"wp-block-table\"><table><thead><tr><td class=\"has-text-align-center\" data-align=\"center\"><strong>__searchQ__ &amp; __searchF__<\/strong><\/td><\/tr><tr><td class=\"has-text-align-center\" data-align=\"center\"><strong><strong><mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-vivid-cyan-blue-color\">CodenerixModel<\/mark><\/strong><\/strong><\/td><td class=\"has-text-align-center\" data-align=\"center\"><strong><strong><mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-vivid-cyan-blue-color\">GenList<\/mark><\/strong><\/strong><\/td><td><strong><strong>Applicable<\/strong><\/strong><\/td><\/tr><\/thead><tbody><tr><td class=\"has-text-align-center\" data-align=\"center\"><mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-vivid-red-color\">NO<\/mark><\/td><td class=\"has-text-align-center\" data-align=\"center\"><mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-vivid-red-color\">NO<\/mark><\/td><td>No filter is applied<\/td><\/tr><tr><td class=\"has-text-align-center\" data-align=\"center\"><mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-vivid-red-color\">NO<\/mark><\/td><td class=\"has-text-align-center\" data-align=\"center\"><mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-vivid-green-cyan-color\">YES<\/mark><\/td><td><strong><strong><strong><mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-vivid-cyan-blue-color\">GenList<\/mark><\/strong><\/strong><\/strong> filter is applied<\/td><\/tr><tr><td class=\"has-text-align-center\" data-align=\"center\"><mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-vivid-green-cyan-color\">YES<\/mark><\/td><td class=\"has-text-align-center\" data-align=\"center\"><mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-vivid-red-color\">NO<\/mark><\/td><td><strong><strong><mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-vivid-cyan-blue-color\">CodenerixModel<\/mark><\/strong><\/strong> filter is applied<\/td><\/tr><tr><td class=\"has-text-align-center\" data-align=\"center\"><mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-vivid-green-cyan-color\">YES<\/mark><\/td><td class=\"has-text-align-center\" data-align=\"center\"><mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-vivid-green-cyan-color\">YES<\/mark><\/td><td><strong><strong><strong><mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-vivid-cyan-blue-color\">GenList<\/mark><\/strong><\/strong><\/strong> filter is applied <\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p>We will remember these tables again later when I explain <strong>GenList<\/strong> in detail.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">And what else?<\/h2>\n\n\n\n<p>In addition to the previous methods, we must point out that <strong>CodenerixModel<\/strong> adds a series of extra functionalities to the standard Django models.<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>By default, it adds the created and updated fields that <strong><a href=\"https:\/\/github.com\/codenerix\/django-codenerix\"><span style=\"color: #343433;\">CODE<\/span><span style=\"color: #70a8e0;\">NERIX<\/span><\/a><\/strong> automatically manages to remember when the record was created and when it was last edited.<\/li>\n\n\n\n<li>It allows the use of a new &#8220;Meta&#8221; class (equivalent to Django&#8217;s) called &#8220;<strong>CodenerixMeta<\/strong>&#8220;.<\/li>\n\n\n\n<li>The standard permissions are replaced by: add, change, delete, view and list. The new types are &#8220;view&#8221; and &#8220;list&#8221; to define if the record can be displayed or listed.<\/li>\n\n\n\n<li>Models also can use the lock_update and lock_delete methods to stop a record update or delete. An example is a record that depends on a specific circumstance of the stored data. These methods allow records to be capriciously blocked in a list, and the user is properly informed of the reason for said blocking. <mark style=\"background-color:#9b51e0\" class=\"has-inline-color has-white-color\">Check source code below (*)<\/mark><\/li>\n\n\n\n<li>In this example, the deletion of a note is prevented when it has associated documents or when people are using it. Otherwise, the responsibility is delegated to the parent class.<br><\/li>\n\n\n\n<li>When a record is going to be deleted, CodenerixModel analyzes the relationships with other models and their deletion protections to respond in a &#8220;<strong>polite<\/strong>&#8221; way in case of trying to delete a record that by model definition (<strong>models.PROTECT<\/strong>) cannot be deleted.<\/li>\n\n\n\n<li>All classes that inherit from <strong>CodenerixModel<\/strong> can also inherit from <strong>GenLog<\/strong>. When doing so, <strong><a href=\"https:\/\/github.com\/codenerix\/django-codenerix\"><span style=\"color: #343433;\">CODE<\/span><span style=\"color: #70a8e0;\">NERIX<\/span><\/a><\/strong> will record in a log any operation that occurs in a record of that class.<\/li>\n<\/ol>\n\n\n\n<p>(*)<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">def lock_delete(self):\n     if self.documents.exists():\n         return (\"The note cannot be deleted, there is a document that blocks it\")\n     elif self.people.exists():\n         return (\"The note cannot be deleted, there are people still working with it\")\n     else:\n         return super(Point, self).lock_delete<\/pre>\n\n\n\n<p>Now we are ready to learn how to use <strong>GenList<\/strong>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>\ud83c\uddea\ud83c\udde6&nbsp;Leer en Espa\u00f1ol, \u201cCodenerixModel\u201c For any Django project to support CODENERIX properly, it is necessary to take some important steps to ensure a good start to the project. We will not repeat that using the CODENERIX Examples available on GitHub is the easiest way to get started. That is why this time, we will focus [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":379,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_et_pb_use_builder":"","_et_pb_old_content":"","_et_gb_content_width":"","_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"footnotes":""},"categories":[20],"tags":[],"class_list":["post-608","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-howto"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.0 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>CodenerixModel - Codenerix<\/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:\/\/codenerix.com\/en\/codenerixmodel\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"CodenerixModel - Codenerix\" \/>\n<meta property=\"og:description\" content=\"\ud83c\uddea\ud83c\udde6&nbsp;Leer en Espa\u00f1ol, \u201cCodenerixModel\u201c For any Django project to support CODENERIX properly, it is necessary to take some important steps to ensure a good start to the project. We will not repeat that using the CODENERIX Examples available on GitHub is the easiest way to get started. That is why this time, we will focus [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/codenerix.com\/en\/codenerixmodel\/\" \/>\n<meta property=\"og:site_name\" content=\"Codenerix\" \/>\n<meta property=\"article:published_time\" content=\"2018-02-28T21:08:00+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2023-04-06T07:06:54+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/codenerix.com\/wp-content\/uploads\/2017\/03\/Codenerix-Programadores-1.png\" \/>\n\t<meta property=\"og:image:width\" content=\"800\" \/>\n\t<meta property=\"og:image:height\" content=\"800\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Codenerix\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Codenerix\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"9 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/codenerix.com\/en\/codenerixmodel\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/codenerix.com\/en\/codenerixmodel\/\"},\"author\":{\"name\":\"Codenerix\",\"@id\":\"https:\/\/codenerix.com\/#\/schema\/person\/c1dce0f30541a2be119ee8adc332a9af\"},\"headline\":\"CodenerixModel\",\"datePublished\":\"2018-02-28T21:08:00+00:00\",\"dateModified\":\"2023-04-06T07:06:54+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/codenerix.com\/en\/codenerixmodel\/\"},\"wordCount\":1634,\"image\":{\"@id\":\"https:\/\/codenerix.com\/en\/codenerixmodel\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/codenerix.com\/wp-content\/uploads\/2017\/03\/Codenerix-Programadores-1.png\",\"articleSection\":[\"Howto\"],\"inLanguage\":\"en-US\"},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/codenerix.com\/en\/codenerixmodel\/\",\"url\":\"https:\/\/codenerix.com\/en\/codenerixmodel\/\",\"name\":\"CodenerixModel - Codenerix\",\"isPartOf\":{\"@id\":\"https:\/\/codenerix.com\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/codenerix.com\/en\/codenerixmodel\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/codenerix.com\/en\/codenerixmodel\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/codenerix.com\/wp-content\/uploads\/2017\/03\/Codenerix-Programadores-1.png\",\"datePublished\":\"2018-02-28T21:08:00+00:00\",\"dateModified\":\"2023-04-06T07:06:54+00:00\",\"author\":{\"@id\":\"https:\/\/codenerix.com\/#\/schema\/person\/c1dce0f30541a2be119ee8adc332a9af\"},\"breadcrumb\":{\"@id\":\"https:\/\/codenerix.com\/en\/codenerixmodel\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/codenerix.com\/en\/codenerixmodel\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/codenerix.com\/en\/codenerixmodel\/#primaryimage\",\"url\":\"https:\/\/codenerix.com\/wp-content\/uploads\/2017\/03\/Codenerix-Programadores-1.png\",\"contentUrl\":\"https:\/\/codenerix.com\/wp-content\/uploads\/2017\/03\/Codenerix-Programadores-1.png\",\"width\":800,\"height\":800},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/codenerix.com\/en\/codenerixmodel\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/codenerix.com\/en\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"CodenerixModel\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/codenerix.com\/#website\",\"url\":\"https:\/\/codenerix.com\/\",\"name\":\"Codenerix\",\"description\":\"Framework libre Open Source\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/codenerix.com\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Person\",\"@id\":\"https:\/\/codenerix.com\/#\/schema\/person\/c1dce0f30541a2be119ee8adc332a9af\",\"name\":\"Codenerix\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/codenerix.com\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/dee2772994eb5d89e57afac281bca674800da15c6c32fba528dea162570d644d?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/dee2772994eb5d89e57afac281bca674800da15c6c32fba528dea162570d644d?s=96&d=mm&r=g\",\"caption\":\"Codenerix\"},\"url\":\"https:\/\/codenerix.com\/en\/author\/codenerix\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"CodenerixModel - Codenerix","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:\/\/codenerix.com\/en\/codenerixmodel\/","og_locale":"en_US","og_type":"article","og_title":"CodenerixModel - Codenerix","og_description":"\ud83c\uddea\ud83c\udde6&nbsp;Leer en Espa\u00f1ol, \u201cCodenerixModel\u201c For any Django project to support CODENERIX properly, it is necessary to take some important steps to ensure a good start to the project. We will not repeat that using the CODENERIX Examples available on GitHub is the easiest way to get started. That is why this time, we will focus [&hellip;]","og_url":"https:\/\/codenerix.com\/en\/codenerixmodel\/","og_site_name":"Codenerix","article_published_time":"2018-02-28T21:08:00+00:00","article_modified_time":"2023-04-06T07:06:54+00:00","og_image":[{"width":800,"height":800,"url":"https:\/\/codenerix.com\/wp-content\/uploads\/2017\/03\/Codenerix-Programadores-1.png","type":"image\/png"}],"author":"Codenerix","twitter_card":"summary_large_image","twitter_misc":{"Written by":"Codenerix","Est. reading time":"9 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/codenerix.com\/en\/codenerixmodel\/#article","isPartOf":{"@id":"https:\/\/codenerix.com\/en\/codenerixmodel\/"},"author":{"name":"Codenerix","@id":"https:\/\/codenerix.com\/#\/schema\/person\/c1dce0f30541a2be119ee8adc332a9af"},"headline":"CodenerixModel","datePublished":"2018-02-28T21:08:00+00:00","dateModified":"2023-04-06T07:06:54+00:00","mainEntityOfPage":{"@id":"https:\/\/codenerix.com\/en\/codenerixmodel\/"},"wordCount":1634,"image":{"@id":"https:\/\/codenerix.com\/en\/codenerixmodel\/#primaryimage"},"thumbnailUrl":"https:\/\/codenerix.com\/wp-content\/uploads\/2017\/03\/Codenerix-Programadores-1.png","articleSection":["Howto"],"inLanguage":"en-US"},{"@type":"WebPage","@id":"https:\/\/codenerix.com\/en\/codenerixmodel\/","url":"https:\/\/codenerix.com\/en\/codenerixmodel\/","name":"CodenerixModel - Codenerix","isPartOf":{"@id":"https:\/\/codenerix.com\/#website"},"primaryImageOfPage":{"@id":"https:\/\/codenerix.com\/en\/codenerixmodel\/#primaryimage"},"image":{"@id":"https:\/\/codenerix.com\/en\/codenerixmodel\/#primaryimage"},"thumbnailUrl":"https:\/\/codenerix.com\/wp-content\/uploads\/2017\/03\/Codenerix-Programadores-1.png","datePublished":"2018-02-28T21:08:00+00:00","dateModified":"2023-04-06T07:06:54+00:00","author":{"@id":"https:\/\/codenerix.com\/#\/schema\/person\/c1dce0f30541a2be119ee8adc332a9af"},"breadcrumb":{"@id":"https:\/\/codenerix.com\/en\/codenerixmodel\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/codenerix.com\/en\/codenerixmodel\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/codenerix.com\/en\/codenerixmodel\/#primaryimage","url":"https:\/\/codenerix.com\/wp-content\/uploads\/2017\/03\/Codenerix-Programadores-1.png","contentUrl":"https:\/\/codenerix.com\/wp-content\/uploads\/2017\/03\/Codenerix-Programadores-1.png","width":800,"height":800},{"@type":"BreadcrumbList","@id":"https:\/\/codenerix.com\/en\/codenerixmodel\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/codenerix.com\/en\/"},{"@type":"ListItem","position":2,"name":"CodenerixModel"}]},{"@type":"WebSite","@id":"https:\/\/codenerix.com\/#website","url":"https:\/\/codenerix.com\/","name":"Codenerix","description":"Framework libre Open Source","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/codenerix.com\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Person","@id":"https:\/\/codenerix.com\/#\/schema\/person\/c1dce0f30541a2be119ee8adc332a9af","name":"Codenerix","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/codenerix.com\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/dee2772994eb5d89e57afac281bca674800da15c6c32fba528dea162570d644d?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/dee2772994eb5d89e57afac281bca674800da15c6c32fba528dea162570d644d?s=96&d=mm&r=g","caption":"Codenerix"},"url":"https:\/\/codenerix.com\/en\/author\/codenerix\/"}]}},"_links":{"self":[{"href":"https:\/\/codenerix.com\/en\/wp-json\/wp\/v2\/posts\/608","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/codenerix.com\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/codenerix.com\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/codenerix.com\/en\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/codenerix.com\/en\/wp-json\/wp\/v2\/comments?post=608"}],"version-history":[{"count":46,"href":"https:\/\/codenerix.com\/en\/wp-json\/wp\/v2\/posts\/608\/revisions"}],"predecessor-version":[{"id":881,"href":"https:\/\/codenerix.com\/en\/wp-json\/wp\/v2\/posts\/608\/revisions\/881"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/codenerix.com\/en\/wp-json\/wp\/v2\/media\/379"}],"wp:attachment":[{"href":"https:\/\/codenerix.com\/en\/wp-json\/wp\/v2\/media?parent=608"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/codenerix.com\/en\/wp-json\/wp\/v2\/categories?post=608"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/codenerix.com\/en\/wp-json\/wp\/v2\/tags?post=608"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}