We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Make foreign key to study in publications.Publication required
### Subject of the issue

The save() method of publications.Publication requires a related study. But the existence of a related study is not enforced.

Remove "null=True" and "blank=True".

https://github.com/ddionrails/ddionrails/blob/191e0f0fa95c81e58783a1b1317e0c705a19e51a/ddionrails/publications/models.py#L50-L57

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `ddionrails/publications/models.py`
Content:
```
1 # -*- coding: utf-8 -*-
2 """ Model definitions for ddionrails.publications app """
3 
4 import uuid
5 from typing import Dict
6 
7 from django.db import models
8 from django.urls import reverse
9 
10 from config.helpers import render_markdown
11 from ddionrails.base.mixins import ModelMixin as DorMixin
12 from ddionrails.data.models import Dataset, Variable
13 from ddionrails.elastic.mixins import ModelMixin as ElasticMixin
14 from ddionrails.instruments.models import Instrument, Question
15 from ddionrails.studies.models import Study
16 
17 
18 class Publication(ElasticMixin, DorMixin, models.Model):
19     """
20     Stores a single publication, related to :model:`studies.Study`.
21     """
22 
23     ##############
24     # attributes #
25     ##############
26     id = models.UUIDField(  # pylint: disable=C0103
27         primary_key=True,
28         default=uuid.uuid4,
29         editable=True,
30         db_index=True,
31         help_text="UUID of the publication. Dependent on the associated study.",
32     )
33 
34     name = models.CharField(
35         max_length=255, db_index=True, help_text="Name of the publication"
36     )
37     sub_type = models.CharField(
38         max_length=255,
39         blank=True,
40         help_text="Type of the publication (e.g., journal article or dissertation)",
41     )
42     title = models.TextField(blank=True, help_text="Title of the publication")
43     author = models.TextField(blank=True, help_text="Name(s) of the author(s)")
44     year = models.TextField(blank=True, help_text="Year of publication")
45     abstract = models.TextField(blank=True, help_text="Abstract of the publication")
46     cite = models.TextField(blank=True, help_text="Suggested citation of the publication")
47     url = models.TextField(
48         blank=True, verbose_name="URL", help_text="URL referencing the publication"
49     )
50     doi = models.TextField(
51         blank=True,
52         verbose_name="DOI",
53         help_text="DOI of the publication (DOI only, not the URL to the DOI)",
54     )
55     studies = models.TextField(
56         blank=True,
57         help_text="Description of studies/data sources used in the publication",
58     )
59 
60     #############
61     # relations #
62     #############
63     study = models.ForeignKey(
64         Study,
65         blank=True,
66         null=True,
67         related_name="publications",
68         on_delete=models.CASCADE,
69         help_text="Foreign key to studies.Study",
70     )
71 
72     # Used by ElasticMixin when indexed into Elasticsearch
73     DOC_TYPE = "publication"
74 
75     def save(
76         self, force_insert=False, force_update=False, using=None, update_fields=None
77     ):
78         """"Set id and call parents save(). """
79         self.id = uuid.uuid5(self.study_id, self.name)  # pylint: disable=C0103
80         super().save(
81             force_insert=force_insert,
82             force_update=force_update,
83             using=using,
84             update_fields=update_fields,
85         )
86 
87     class Meta:  # pylint: disable=missing-docstring,too-few-public-methods
88         unique_together = ("study", "name")
89 
90     def __str__(self) -> str:
91         """ Returns a string representation using the "study" and "name" fields """
92         return f"{self.study}/publ/{self.name}"
93 
94     def get_absolute_url(self) -> str:
95         """ Returns a canonical URL for the model using the "study" and "name" fields """
96         return reverse(
97             "publ:publication",
98             kwargs={"study_name": self.study.name, "publication_name": self.name},
99         )
100 
101     def html_abstract(self) -> str:
102         """ Returns the "abstract" field as a string containing HTML markup """
103         return render_markdown(self.abstract)
104 
105     def html_cite(self) -> str:
106         """ Returns the "cite" field as a string containing HTML markup """
107         return render_markdown(self.cite)
108 
109     def to_elastic_dict(self) -> Dict[str, str]:
110         """ Returns a dictionary to be indexed by Elasticsearch """
111         try:
112             study_name = self.study.name
113         except AttributeError:
114             study_name = ""
115         return dict(
116             name=self.name,
117             sub_type=self.sub_type,
118             title=self.title,
119             author=self.author,
120             year=self.year,
121             period=self.year,
122             abstract=self.abstract,
123             cite=self.cite,
124             url=self.url,
125             doi=self.doi,
126             study=study_name,
127         )
128 
129 
130 class Attachment(models.Model):
131     """
132     Stores a single attachment, related to:
133     :model:`studies.Study`,
134     :model:`data.Dataset`,
135     :model:`data.Variable`,
136     :model:`instruments.Instrument` and
137     :model:`instruments.Question`
138 
139     """
140 
141     ##############
142     # attributes #
143     ##############
144     url = models.TextField(
145         blank=True, verbose_name="URL", help_text="Link (URL) to the attachment"
146     )
147     url_text = models.TextField(
148         blank=True, verbose_name="URL text", help_text="Text to be displayed for the link"
149     )
150 
151     #############
152     # relations #
153     #############
154     context_study = models.ForeignKey(
155         Study,
156         related_name="related_attachments",
157         on_delete=models.CASCADE,
158         help_text="Foreign key to studies.Study",
159     )
160     study = models.ForeignKey(
161         Study,
162         blank=True,
163         null=True,
164         related_name="attachments",
165         on_delete=models.CASCADE,
166         help_text="Foreign key to studies.Study",
167     )
168     dataset = models.ForeignKey(
169         Dataset,
170         blank=True,
171         null=True,
172         related_name="attachments",
173         on_delete=models.CASCADE,
174         help_text="Foreign key to data.Dataset",
175     )
176     variable = models.ForeignKey(
177         Variable,
178         blank=True,
179         null=True,
180         related_name="attachments",
181         on_delete=models.CASCADE,
182         help_text="Foreign key to data.Variable",
183     )
184     instrument = models.ForeignKey(
185         Instrument,
186         blank=True,
187         null=True,
188         related_name="attachments",
189         on_delete=models.CASCADE,
190         help_text="Foreign key to instruments.Instrument",
191     )
192     question = models.ForeignKey(
193         Question,
194         blank=True,
195         null=True,
196         related_name="attachments",
197         on_delete=models.CASCADE,
198         help_text="Foreign key to instruments.Question",
199     )
200
```

Path: `ddionrails/publications/migrations/0001_initial.py`
Content:
```
1 # Generated by Django 2.2.2 on 2019-06-27 11:16
2 
3 import uuid
4 
5 import django.db.models.deletion
6 from django.db import migrations, models
7 
8 import ddionrails.base.mixins
9 import ddionrails.elastic.mixins
10 
11 
12 class Migration(migrations.Migration):
13 
14     initial = True
15 
16     dependencies = [
17         ("instruments", "__first__"),
18         ("data", "0001_initial"),
19         ("studies", "0001_initial"),
20     ]
21 
22     operations = [
23         migrations.CreateModel(
24             name="Attachment",
25             fields=[
26                 (
27                     "id",
28                     models.AutoField(
29                         auto_created=True,
30                         primary_key=True,
31                         serialize=False,
32                         verbose_name="ID",
33                     ),
34                 ),
35                 (
36                     "url",
37                     models.TextField(
38                         blank=True,
39                         help_text="Link (URL) to the attachment",
40                         verbose_name="URL",
41                     ),
42                 ),
43                 (
44                     "url_text",
45                     models.TextField(
46                         blank=True,
47                         help_text="Text to be displayed for the link",
48                         verbose_name="URL text",
49                     ),
50                 ),
51                 (
52                     "context_study",
53                     models.ForeignKey(
54                         help_text="Foreign key to studies.Study",
55                         on_delete=django.db.models.deletion.CASCADE,
56                         related_name="related_attachments",
57                         to="studies.Study",
58                     ),
59                 ),
60                 (
61                     "dataset",
62                     models.ForeignKey(
63                         blank=True,
64                         help_text="Foreign key to data.Dataset",
65                         null=True,
66                         on_delete=django.db.models.deletion.CASCADE,
67                         related_name="attachments",
68                         to="data.Dataset",
69                     ),
70                 ),
71                 (
72                     "instrument",
73                     models.ForeignKey(
74                         blank=True,
75                         help_text="Foreign key to instruments.Instrument",
76                         null=True,
77                         on_delete=django.db.models.deletion.CASCADE,
78                         related_name="attachments",
79                         to="instruments.Instrument",
80                     ),
81                 ),
82                 (
83                     "question",
84                     models.ForeignKey(
85                         blank=True,
86                         help_text="Foreign key to instruments.Question",
87                         null=True,
88                         on_delete=django.db.models.deletion.CASCADE,
89                         related_name="attachments",
90                         to="instruments.Question",
91                     ),
92                 ),
93                 (
94                     "study",
95                     models.ForeignKey(
96                         blank=True,
97                         help_text="Foreign key to studies.Study",
98                         null=True,
99                         on_delete=django.db.models.deletion.CASCADE,
100                         related_name="attachments",
101                         to="studies.Study",
102                     ),
103                 ),
104                 (
105                     "variable",
106                     models.ForeignKey(
107                         blank=True,
108                         help_text="Foreign key to data.Variable",
109                         null=True,
110                         on_delete=django.db.models.deletion.CASCADE,
111                         related_name="attachments",
112                         to="data.Variable",
113                     ),
114                 ),
115             ],
116         ),
117         migrations.CreateModel(
118             name="Publication",
119             fields=[
120                 (
121                     "id",
122                     models.UUIDField(
123                         db_index=True,
124                         default=uuid.uuid4,
125                         help_text="UUID of the publication. Dependent on the associated study.",
126                         primary_key=True,
127                         serialize=False,
128                     ),
129                 ),
130                 (
131                     "name",
132                     models.CharField(
133                         db_index=True, help_text="Name of the publication", max_length=255
134                     ),
135                 ),
136                 (
137                     "sub_type",
138                     models.CharField(
139                         blank=True,
140                         help_text="Type of the publication (e.g., journal article or dissertation)",
141                         max_length=255,
142                     ),
143                 ),
144                 (
145                     "title",
146                     models.TextField(blank=True, help_text="Title of the publication"),
147                 ),
148                 (
149                     "author",
150                     models.TextField(blank=True, help_text="Name(s) of the author(s)"),
151                 ),
152                 ("year", models.TextField(blank=True, help_text="Year of publication")),
153                 (
154                     "abstract",
155                     models.TextField(blank=True, help_text="Abstract of the publication"),
156                 ),
157                 (
158                     "cite",
159                     models.TextField(
160                         blank=True, help_text="Suggested citation of the publication"
161                     ),
162                 ),
163                 (
164                     "url",
165                     models.TextField(
166                         blank=True,
167                         help_text="URL referencing the publication",
168                         verbose_name="URL",
169                     ),
170                 ),
171                 (
172                     "doi",
173                     models.TextField(
174                         blank=True,
175                         help_text="DOI of the publication (DOI only, not the URL to the DOI)",
176                         verbose_name="DOI",
177                     ),
178                 ),
179                 (
180                     "studies",
181                     models.TextField(
182                         blank=True,
183                         help_text="Description of studies/data sources used in the publication",
184                     ),
185                 ),
186                 (
187                     "study",
188                     models.ForeignKey(
189                         blank=True,
190                         help_text="Foreign key to studies.Study",
191                         null=True,
192                         on_delete=django.db.models.deletion.CASCADE,
193                         related_name="publications",
194                         to="studies.Study",
195                     ),
196                 ),
197             ],
198             options={"unique_together": {("study", "name")}},
199             bases=(
200                 ddionrails.elastic.mixins.ModelMixin,
201                 ddionrails.base.mixins.ModelMixin,
202                 models.Model,
203             ),
204         ),
205     ]
206
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/ddionrails/publications/migrations/0001_initial.py b/ddionrails/publications/migrations/0001_initial.py
--- a/ddionrails/publications/migrations/0001_initial.py
+++ b/ddionrails/publications/migrations/0001_initial.py
@@ -186,9 +186,7 @@
                 (
                     "study",
                     models.ForeignKey(
-                        blank=True,
                         help_text="Foreign key to studies.Study",
-                        null=True,
                         on_delete=django.db.models.deletion.CASCADE,
                         related_name="publications",
                         to="studies.Study",
diff --git a/ddionrails/publications/models.py b/ddionrails/publications/models.py
--- a/ddionrails/publications/models.py
+++ b/ddionrails/publications/models.py
@@ -62,8 +62,6 @@
     #############
     study = models.ForeignKey(
         Study,
-        blank=True,
-        null=True,
         related_name="publications",
         on_delete=models.CASCADE,
         help_text="Foreign key to studies.Study",

{"golden_diff": "diff --git a/ddionrails/publications/migrations/0001_initial.py b/ddionrails/publications/migrations/0001_initial.py\n--- a/ddionrails/publications/migrations/0001_initial.py\n+++ b/ddionrails/publications/migrations/0001_initial.py\n@@ -186,9 +186,7 @@\n                 (\n                     \"study\",\n                     models.ForeignKey(\n-                        blank=True,\n                         help_text=\"Foreign key to studies.Study\",\n-                        null=True,\n                         on_delete=django.db.models.deletion.CASCADE,\n                         related_name=\"publications\",\n                         to=\"studies.Study\",\ndiff --git a/ddionrails/publications/models.py b/ddionrails/publications/models.py\n--- a/ddionrails/publications/models.py\n+++ b/ddionrails/publications/models.py\n@@ -62,8 +62,6 @@\n     #############\n     study = models.ForeignKey(\n         Study,\n-        blank=True,\n-        null=True,\n         related_name=\"publications\",\n         on_delete=models.CASCADE,\n         help_text=\"Foreign key to studies.Study\",\n", "issue": "Make foreign key to study in publications.Publication required\n### Subject of the issue\r\n\r\nThe save() method of publications.Publication requires a related study. But the existence of a related study is not enforced.\r\n\r\nRemove \"null=True\" and \"blank=True\".\r\n\r\nhttps://github.com/ddionrails/ddionrails/blob/191e0f0fa95c81e58783a1b1317e0c705a19e51a/ddionrails/publications/models.py#L50-L57\n", "before_files": [{"content": "# -*- coding: utf-8 -*-\n\"\"\" Model definitions for ddionrails.publications app \"\"\"\n\nimport uuid\nfrom typing import Dict\n\nfrom django.db import models\nfrom django.urls import reverse\n\nfrom config.helpers import render_markdown\nfrom ddionrails.base.mixins import ModelMixin as DorMixin\nfrom ddionrails.data.models import Dataset, Variable\nfrom ddionrails.elastic.mixins import ModelMixin as ElasticMixin\nfrom ddionrails.instruments.models import Instrument, Question\nfrom ddionrails.studies.models import Study\n\n\nclass Publication(ElasticMixin, DorMixin, models.Model):\n    \"\"\"\n    Stores a single publication, related to :model:`studies.Study`.\n    \"\"\"\n\n    ##############\n    # attributes #\n    ##############\n    id = models.UUIDField(  # pylint: disable=C0103\n        primary_key=True,\n        default=uuid.uuid4,\n        editable=True,\n        db_index=True,\n        help_text=\"UUID of the publication. Dependent on the associated study.\",\n    )\n\n    name = models.CharField(\n        max_length=255, db_index=True, help_text=\"Name of the publication\"\n    )\n    sub_type = models.CharField(\n        max_length=255,\n        blank=True,\n        help_text=\"Type of the publication (e.g., journal article or dissertation)\",\n    )\n    title = models.TextField(blank=True, help_text=\"Title of the publication\")\n    author = models.TextField(blank=True, help_text=\"Name(s) of the author(s)\")\n    year = models.TextField(blank=True, help_text=\"Year of publication\")\n    abstract = models.TextField(blank=True, help_text=\"Abstract of the publication\")\n    cite = models.TextField(blank=True, help_text=\"Suggested citation of the publication\")\n    url = models.TextField(\n        blank=True, verbose_name=\"URL\", help_text=\"URL referencing the publication\"\n    )\n    doi = models.TextField(\n        blank=True,\n        verbose_name=\"DOI\",\n        help_text=\"DOI of the publication (DOI only, not the URL to the DOI)\",\n    )\n    studies = models.TextField(\n        blank=True,\n        help_text=\"Description of studies/data sources used in the publication\",\n    )\n\n    #############\n    # relations #\n    #############\n    study = models.ForeignKey(\n        Study,\n        blank=True,\n        null=True,\n        related_name=\"publications\",\n        on_delete=models.CASCADE,\n        help_text=\"Foreign key to studies.Study\",\n    )\n\n    # Used by ElasticMixin when indexed into Elasticsearch\n    DOC_TYPE = \"publication\"\n\n    def save(\n        self, force_insert=False, force_update=False, using=None, update_fields=None\n    ):\n        \"\"\"\"Set id and call parents save(). \"\"\"\n        self.id = uuid.uuid5(self.study_id, self.name)  # pylint: disable=C0103\n        super().save(\n            force_insert=force_insert,\n            force_update=force_update,\n            using=using,\n            update_fields=update_fields,\n        )\n\n    class Meta:  # pylint: disable=missing-docstring,too-few-public-methods\n        unique_together = (\"study\", \"name\")\n\n    def __str__(self) -> str:\n        \"\"\" Returns a string representation using the \"study\" and \"name\" fields \"\"\"\n        return f\"{self.study}/publ/{self.name}\"\n\n    def get_absolute_url(self) -> str:\n        \"\"\" Returns a canonical URL for the model using the \"study\" and \"name\" fields \"\"\"\n        return reverse(\n            \"publ:publication\",\n            kwargs={\"study_name\": self.study.name, \"publication_name\": self.name},\n        )\n\n    def html_abstract(self) -> str:\n        \"\"\" Returns the \"abstract\" field as a string containing HTML markup \"\"\"\n        return render_markdown(self.abstract)\n\n    def html_cite(self) -> str:\n        \"\"\" Returns the \"cite\" field as a string containing HTML markup \"\"\"\n        return render_markdown(self.cite)\n\n    def to_elastic_dict(self) -> Dict[str, str]:\n        \"\"\" Returns a dictionary to be indexed by Elasticsearch \"\"\"\n        try:\n            study_name = self.study.name\n        except AttributeError:\n            study_name = \"\"\n        return dict(\n            name=self.name,\n            sub_type=self.sub_type,\n            title=self.title,\n            author=self.author,\n            year=self.year,\n            period=self.year,\n            abstract=self.abstract,\n            cite=self.cite,\n            url=self.url,\n            doi=self.doi,\n            study=study_name,\n        )\n\n\nclass Attachment(models.Model):\n    \"\"\"\n    Stores a single attachment, related to:\n    :model:`studies.Study`,\n    :model:`data.Dataset`,\n    :model:`data.Variable`,\n    :model:`instruments.Instrument` and\n    :model:`instruments.Question`\n\n    \"\"\"\n\n    ##############\n    # attributes #\n    ##############\n    url = models.TextField(\n        blank=True, verbose_name=\"URL\", help_text=\"Link (URL) to the attachment\"\n    )\n    url_text = models.TextField(\n        blank=True, verbose_name=\"URL text\", help_text=\"Text to be displayed for the link\"\n    )\n\n    #############\n    # relations #\n    #############\n    context_study = models.ForeignKey(\n        Study,\n        related_name=\"related_attachments\",\n        on_delete=models.CASCADE,\n        help_text=\"Foreign key to studies.Study\",\n    )\n    study = models.ForeignKey(\n        Study,\n        blank=True,\n        null=True,\n        related_name=\"attachments\",\n        on_delete=models.CASCADE,\n        help_text=\"Foreign key to studies.Study\",\n    )\n    dataset = models.ForeignKey(\n        Dataset,\n        blank=True,\n        null=True,\n        related_name=\"attachments\",\n        on_delete=models.CASCADE,\n        help_text=\"Foreign key to data.Dataset\",\n    )\n    variable = models.ForeignKey(\n        Variable,\n        blank=True,\n        null=True,\n        related_name=\"attachments\",\n        on_delete=models.CASCADE,\n        help_text=\"Foreign key to data.Variable\",\n    )\n    instrument = models.ForeignKey(\n        Instrument,\n        blank=True,\n        null=True,\n        related_name=\"attachments\",\n        on_delete=models.CASCADE,\n        help_text=\"Foreign key to instruments.Instrument\",\n    )\n    question = models.ForeignKey(\n        Question,\n        blank=True,\n        null=True,\n        related_name=\"attachments\",\n        on_delete=models.CASCADE,\n        help_text=\"Foreign key to instruments.Question\",\n    )\n", "path": "ddionrails/publications/models.py"}, {"content": "# Generated by Django 2.2.2 on 2019-06-27 11:16\n\nimport uuid\n\nimport django.db.models.deletion\nfrom django.db import migrations, models\n\nimport ddionrails.base.mixins\nimport ddionrails.elastic.mixins\n\n\nclass Migration(migrations.Migration):\n\n    initial = True\n\n    dependencies = [\n        (\"instruments\", \"__first__\"),\n        (\"data\", \"0001_initial\"),\n        (\"studies\", \"0001_initial\"),\n    ]\n\n    operations = [\n        migrations.CreateModel(\n            name=\"Attachment\",\n            fields=[\n                (\n                    \"id\",\n                    models.AutoField(\n                        auto_created=True,\n                        primary_key=True,\n                        serialize=False,\n                        verbose_name=\"ID\",\n                    ),\n                ),\n                (\n                    \"url\",\n                    models.TextField(\n                        blank=True,\n                        help_text=\"Link (URL) to the attachment\",\n                        verbose_name=\"URL\",\n                    ),\n                ),\n                (\n                    \"url_text\",\n                    models.TextField(\n                        blank=True,\n                        help_text=\"Text to be displayed for the link\",\n                        verbose_name=\"URL text\",\n                    ),\n                ),\n                (\n                    \"context_study\",\n                    models.ForeignKey(\n                        help_text=\"Foreign key to studies.Study\",\n                        on_delete=django.db.models.deletion.CASCADE,\n                        related_name=\"related_attachments\",\n                        to=\"studies.Study\",\n                    ),\n                ),\n                (\n                    \"dataset\",\n                    models.ForeignKey(\n                        blank=True,\n                        help_text=\"Foreign key to data.Dataset\",\n                        null=True,\n                        on_delete=django.db.models.deletion.CASCADE,\n                        related_name=\"attachments\",\n                        to=\"data.Dataset\",\n                    ),\n                ),\n                (\n                    \"instrument\",\n                    models.ForeignKey(\n                        blank=True,\n                        help_text=\"Foreign key to instruments.Instrument\",\n                        null=True,\n                        on_delete=django.db.models.deletion.CASCADE,\n                        related_name=\"attachments\",\n                        to=\"instruments.Instrument\",\n                    ),\n                ),\n                (\n                    \"question\",\n                    models.ForeignKey(\n                        blank=True,\n                        help_text=\"Foreign key to instruments.Question\",\n                        null=True,\n                        on_delete=django.db.models.deletion.CASCADE,\n                        related_name=\"attachments\",\n                        to=\"instruments.Question\",\n                    ),\n                ),\n                (\n                    \"study\",\n                    models.ForeignKey(\n                        blank=True,\n                        help_text=\"Foreign key to studies.Study\",\n                        null=True,\n                        on_delete=django.db.models.deletion.CASCADE,\n                        related_name=\"attachments\",\n                        to=\"studies.Study\",\n                    ),\n                ),\n                (\n                    \"variable\",\n                    models.ForeignKey(\n                        blank=True,\n                        help_text=\"Foreign key to data.Variable\",\n                        null=True,\n                        on_delete=django.db.models.deletion.CASCADE,\n                        related_name=\"attachments\",\n                        to=\"data.Variable\",\n                    ),\n                ),\n            ],\n        ),\n        migrations.CreateModel(\n            name=\"Publication\",\n            fields=[\n                (\n                    \"id\",\n                    models.UUIDField(\n                        db_index=True,\n                        default=uuid.uuid4,\n                        help_text=\"UUID of the publication. Dependent on the associated study.\",\n                        primary_key=True,\n                        serialize=False,\n                    ),\n                ),\n                (\n                    \"name\",\n                    models.CharField(\n                        db_index=True, help_text=\"Name of the publication\", max_length=255\n                    ),\n                ),\n                (\n                    \"sub_type\",\n                    models.CharField(\n                        blank=True,\n                        help_text=\"Type of the publication (e.g., journal article or dissertation)\",\n                        max_length=255,\n                    ),\n                ),\n                (\n                    \"title\",\n                    models.TextField(blank=True, help_text=\"Title of the publication\"),\n                ),\n                (\n                    \"author\",\n                    models.TextField(blank=True, help_text=\"Name(s) of the author(s)\"),\n                ),\n                (\"year\", models.TextField(blank=True, help_text=\"Year of publication\")),\n                (\n                    \"abstract\",\n                    models.TextField(blank=True, help_text=\"Abstract of the publication\"),\n                ),\n                (\n                    \"cite\",\n                    models.TextField(\n                        blank=True, help_text=\"Suggested citation of the publication\"\n                    ),\n                ),\n                (\n                    \"url\",\n                    models.TextField(\n                        blank=True,\n                        help_text=\"URL referencing the publication\",\n                        verbose_name=\"URL\",\n                    ),\n                ),\n                (\n                    \"doi\",\n                    models.TextField(\n                        blank=True,\n                        help_text=\"DOI of the publication (DOI only, not the URL to the DOI)\",\n                        verbose_name=\"DOI\",\n                    ),\n                ),\n                (\n                    \"studies\",\n                    models.TextField(\n                        blank=True,\n                        help_text=\"Description of studies/data sources used in the publication\",\n                    ),\n                ),\n                (\n                    \"study\",\n                    models.ForeignKey(\n                        blank=True,\n                        help_text=\"Foreign key to studies.Study\",\n                        null=True,\n                        on_delete=django.db.models.deletion.CASCADE,\n                        related_name=\"publications\",\n                        to=\"studies.Study\",\n                    ),\n                ),\n            ],\n            options={\"unique_together\": {(\"study\", \"name\")}},\n            bases=(\n                ddionrails.elastic.mixins.ModelMixin,\n                ddionrails.base.mixins.ModelMixin,\n                models.Model,\n            ),\n        ),\n    ]\n", "path": "ddionrails/publications/migrations/0001_initial.py"}], "after_files": [{"content": "# -*- coding: utf-8 -*-\n\"\"\" Model definitions for ddionrails.publications app \"\"\"\n\nimport uuid\nfrom typing import Dict\n\nfrom django.db import models\nfrom django.urls import reverse\n\nfrom config.helpers import render_markdown\nfrom ddionrails.base.mixins import ModelMixin as DorMixin\nfrom ddionrails.data.models import Dataset, Variable\nfrom ddionrails.elastic.mixins import ModelMixin as ElasticMixin\nfrom ddionrails.instruments.models import Instrument, Question\nfrom ddionrails.studies.models import Study\n\n\nclass Publication(ElasticMixin, DorMixin, models.Model):\n    \"\"\"\n    Stores a single publication, related to :model:`studies.Study`.\n    \"\"\"\n\n    ##############\n    # attributes #\n    ##############\n    id = models.UUIDField(  # pylint: disable=C0103\n        primary_key=True,\n        default=uuid.uuid4,\n        editable=True,\n        db_index=True,\n        help_text=\"UUID of the publication. Dependent on the associated study.\",\n    )\n\n    name = models.CharField(\n        max_length=255, db_index=True, help_text=\"Name of the publication\"\n    )\n    sub_type = models.CharField(\n        max_length=255,\n        blank=True,\n        help_text=\"Type of the publication (e.g., journal article or dissertation)\",\n    )\n    title = models.TextField(blank=True, help_text=\"Title of the publication\")\n    author = models.TextField(blank=True, help_text=\"Name(s) of the author(s)\")\n    year = models.TextField(blank=True, help_text=\"Year of publication\")\n    abstract = models.TextField(blank=True, help_text=\"Abstract of the publication\")\n    cite = models.TextField(blank=True, help_text=\"Suggested citation of the publication\")\n    url = models.TextField(\n        blank=True, verbose_name=\"URL\", help_text=\"URL referencing the publication\"\n    )\n    doi = models.TextField(\n        blank=True,\n        verbose_name=\"DOI\",\n        help_text=\"DOI of the publication (DOI only, not the URL to the DOI)\",\n    )\n    studies = models.TextField(\n        blank=True,\n        help_text=\"Description of studies/data sources used in the publication\",\n    )\n\n    #############\n    # relations #\n    #############\n    study = models.ForeignKey(\n        Study,\n        related_name=\"publications\",\n        on_delete=models.CASCADE,\n        help_text=\"Foreign key to studies.Study\",\n    )\n\n    # Used by ElasticMixin when indexed into Elasticsearch\n    DOC_TYPE = \"publication\"\n\n    def save(\n        self, force_insert=False, force_update=False, using=None, update_fields=None\n    ):\n        \"\"\"\"Set id and call parents save(). \"\"\"\n        self.id = uuid.uuid5(self.study_id, self.name)  # pylint: disable=C0103\n        super().save(\n            force_insert=force_insert,\n            force_update=force_update,\n            using=using,\n            update_fields=update_fields,\n        )\n\n    class Meta:  # pylint: disable=missing-docstring,too-few-public-methods\n        unique_together = (\"study\", \"name\")\n\n    def __str__(self) -> str:\n        \"\"\" Returns a string representation using the \"study\" and \"name\" fields \"\"\"\n        return f\"{self.study}/publ/{self.name}\"\n\n    def get_absolute_url(self) -> str:\n        \"\"\" Returns a canonical URL for the model using the \"study\" and \"name\" fields \"\"\"\n        return reverse(\n            \"publ:publication\",\n            kwargs={\"study_name\": self.study.name, \"publication_name\": self.name},\n        )\n\n    def html_abstract(self) -> str:\n        \"\"\" Returns the \"abstract\" field as a string containing HTML markup \"\"\"\n        return render_markdown(self.abstract)\n\n    def html_cite(self) -> str:\n        \"\"\" Returns the \"cite\" field as a string containing HTML markup \"\"\"\n        return render_markdown(self.cite)\n\n    def to_elastic_dict(self) -> Dict[str, str]:\n        \"\"\" Returns a dictionary to be indexed by Elasticsearch \"\"\"\n        try:\n            study_name = self.study.name\n        except AttributeError:\n            study_name = \"\"\n        return dict(\n            name=self.name,\n            sub_type=self.sub_type,\n            title=self.title,\n            author=self.author,\n            year=self.year,\n            period=self.year,\n            abstract=self.abstract,\n            cite=self.cite,\n            url=self.url,\n            doi=self.doi,\n            study=study_name,\n        )\n\n\nclass Attachment(models.Model):\n    \"\"\"\n    Stores a single attachment, related to:\n    :model:`studies.Study`,\n    :model:`data.Dataset`,\n    :model:`data.Variable`,\n    :model:`instruments.Instrument` and\n    :model:`instruments.Question`\n\n    \"\"\"\n\n    ##############\n    # attributes #\n    ##############\n    url = models.TextField(\n        blank=True, verbose_name=\"URL\", help_text=\"Link (URL) to the attachment\"\n    )\n    url_text = models.TextField(\n        blank=True, verbose_name=\"URL text\", help_text=\"Text to be displayed for the link\"\n    )\n\n    #############\n    # relations #\n    #############\n    context_study = models.ForeignKey(\n        Study,\n        related_name=\"related_attachments\",\n        on_delete=models.CASCADE,\n        help_text=\"Foreign key to studies.Study\",\n    )\n    study = models.ForeignKey(\n        Study,\n        blank=True,\n        null=True,\n        related_name=\"attachments\",\n        on_delete=models.CASCADE,\n        help_text=\"Foreign key to studies.Study\",\n    )\n    dataset = models.ForeignKey(\n        Dataset,\n        blank=True,\n        null=True,\n        related_name=\"attachments\",\n        on_delete=models.CASCADE,\n        help_text=\"Foreign key to data.Dataset\",\n    )\n    variable = models.ForeignKey(\n        Variable,\n        blank=True,\n        null=True,\n        related_name=\"attachments\",\n        on_delete=models.CASCADE,\n        help_text=\"Foreign key to data.Variable\",\n    )\n    instrument = models.ForeignKey(\n        Instrument,\n        blank=True,\n        null=True,\n        related_name=\"attachments\",\n        on_delete=models.CASCADE,\n        help_text=\"Foreign key to instruments.Instrument\",\n    )\n    question = models.ForeignKey(\n        Question,\n        blank=True,\n        null=True,\n        related_name=\"attachments\",\n        on_delete=models.CASCADE,\n        help_text=\"Foreign key to instruments.Question\",\n    )\n", "path": "ddionrails/publications/models.py"}, {"content": "# Generated by Django 2.2.2 on 2019-06-27 11:16\n\nimport uuid\n\nimport django.db.models.deletion\nfrom django.db import migrations, models\n\nimport ddionrails.base.mixins\nimport ddionrails.elastic.mixins\n\n\nclass Migration(migrations.Migration):\n\n    initial = True\n\n    dependencies = [\n        (\"instruments\", \"__first__\"),\n        (\"data\", \"0001_initial\"),\n        (\"studies\", \"0001_initial\"),\n    ]\n\n    operations = [\n        migrations.CreateModel(\n            name=\"Attachment\",\n            fields=[\n                (\n                    \"id\",\n                    models.AutoField(\n                        auto_created=True,\n                        primary_key=True,\n                        serialize=False,\n                        verbose_name=\"ID\",\n                    ),\n                ),\n                (\n                    \"url\",\n                    models.TextField(\n                        blank=True,\n                        help_text=\"Link (URL) to the attachment\",\n                        verbose_name=\"URL\",\n                    ),\n                ),\n                (\n                    \"url_text\",\n                    models.TextField(\n                        blank=True,\n                        help_text=\"Text to be displayed for the link\",\n                        verbose_name=\"URL text\",\n                    ),\n                ),\n                (\n                    \"context_study\",\n                    models.ForeignKey(\n                        help_text=\"Foreign key to studies.Study\",\n                        on_delete=django.db.models.deletion.CASCADE,\n                        related_name=\"related_attachments\",\n                        to=\"studies.Study\",\n                    ),\n                ),\n                (\n                    \"dataset\",\n                    models.ForeignKey(\n                        blank=True,\n                        help_text=\"Foreign key to data.Dataset\",\n                        null=True,\n                        on_delete=django.db.models.deletion.CASCADE,\n                        related_name=\"attachments\",\n                        to=\"data.Dataset\",\n                    ),\n                ),\n                (\n                    \"instrument\",\n                    models.ForeignKey(\n                        blank=True,\n                        help_text=\"Foreign key to instruments.Instrument\",\n                        null=True,\n                        on_delete=django.db.models.deletion.CASCADE,\n                        related_name=\"attachments\",\n                        to=\"instruments.Instrument\",\n                    ),\n                ),\n                (\n                    \"question\",\n                    models.ForeignKey(\n                        blank=True,\n                        help_text=\"Foreign key to instruments.Question\",\n                        null=True,\n                        on_delete=django.db.models.deletion.CASCADE,\n                        related_name=\"attachments\",\n                        to=\"instruments.Question\",\n                    ),\n                ),\n                (\n                    \"study\",\n                    models.ForeignKey(\n                        blank=True,\n                        help_text=\"Foreign key to studies.Study\",\n                        null=True,\n                        on_delete=django.db.models.deletion.CASCADE,\n                        related_name=\"attachments\",\n                        to=\"studies.Study\",\n                    ),\n                ),\n                (\n                    \"variable\",\n                    models.ForeignKey(\n                        blank=True,\n                        help_text=\"Foreign key to data.Variable\",\n                        null=True,\n                        on_delete=django.db.models.deletion.CASCADE,\n                        related_name=\"attachments\",\n                        to=\"data.Variable\",\n                    ),\n                ),\n            ],\n        ),\n        migrations.CreateModel(\n            name=\"Publication\",\n            fields=[\n                (\n                    \"id\",\n                    models.UUIDField(\n                        db_index=True,\n                        default=uuid.uuid4,\n                        help_text=\"UUID of the publication. Dependent on the associated study.\",\n                        primary_key=True,\n                        serialize=False,\n                    ),\n                ),\n                (\n                    \"name\",\n                    models.CharField(\n                        db_index=True, help_text=\"Name of the publication\", max_length=255\n                    ),\n                ),\n                (\n                    \"sub_type\",\n                    models.CharField(\n                        blank=True,\n                        help_text=\"Type of the publication (e.g., journal article or dissertation)\",\n                        max_length=255,\n                    ),\n                ),\n                (\n                    \"title\",\n                    models.TextField(blank=True, help_text=\"Title of the publication\"),\n                ),\n                (\n                    \"author\",\n                    models.TextField(blank=True, help_text=\"Name(s) of the author(s)\"),\n                ),\n                (\"year\", models.TextField(blank=True, help_text=\"Year of publication\")),\n                (\n                    \"abstract\",\n                    models.TextField(blank=True, help_text=\"Abstract of the publication\"),\n                ),\n                (\n                    \"cite\",\n                    models.TextField(\n                        blank=True, help_text=\"Suggested citation of the publication\"\n                    ),\n                ),\n                (\n                    \"url\",\n                    models.TextField(\n                        blank=True,\n                        help_text=\"URL referencing the publication\",\n                        verbose_name=\"URL\",\n                    ),\n                ),\n                (\n                    \"doi\",\n                    models.TextField(\n                        blank=True,\n                        help_text=\"DOI of the publication (DOI only, not the URL to the DOI)\",\n                        verbose_name=\"DOI\",\n                    ),\n                ),\n                (\n                    \"studies\",\n                    models.TextField(\n                        blank=True,\n                        help_text=\"Description of studies/data sources used in the publication\",\n                    ),\n                ),\n                (\n                    \"study\",\n                    models.ForeignKey(\n                        help_text=\"Foreign key to studies.Study\",\n                        on_delete=django.db.models.deletion.CASCADE,\n                        related_name=\"publications\",\n                        to=\"studies.Study\",\n                    ),\n                ),\n            ],\n            options={\"unique_together\": {(\"study\", \"name\")}},\n            bases=(\n                ddionrails.elastic.mixins.ModelMixin,\n                ddionrails.base.mixins.ModelMixin,\n                models.Model,\n            ),\n        ),\n    ]\n", "path": "ddionrails/publications/migrations/0001_initial.py"}]}