• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

iplweb / bpp / 0950478e-207f-4389-967f-fb3a6c1090d4

01 Apr 2025 12:57PM UTC coverage: 43.279% (-3.3%) from 46.628%
0950478e-207f-4389-967f-fb3a6c1090d4

push

circleci

mpasternak
Merge branch 'release/v202504.1175'

1 of 19 new or added lines in 5 files covered. (5.26%)

1780 existing lines in 123 files now uncovered.

15876 of 36683 relevant lines covered (43.28%)

0.79 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

69.18
src/bpp/models/cache/rekord.py
1
import denorm
2✔
2
from django.db import connections, models, router
2✔
3
from django.db.models.deletion import DO_NOTHING
2✔
4
from django.urls import reverse
2✔
5
from taggit.managers import TaggableManager, _TaggableManager
2✔
6

7
from .punktacja import Cache_Punktacja_Autora, Cache_Punktacja_Dyscypliny
2✔
8
from .views import SlowaKluczoweView
2✔
9

10
from django.contrib.contenttypes.models import ContentType
2✔
11
from django.contrib.postgres.fields.array import ArrayField
2✔
12
from django.contrib.postgres.search import SearchVectorField as VectorField
2✔
13

14
from django.utils.functional import cached_property
2✔
15

16
from bpp.models.abstract import (
2✔
17
    ModelPunktowanyBaza,
18
    ModelRecenzowany,
19
    ModelTypowany,
20
    ModelZCharakterem,
21
    ModelZDOI,
22
    ModelZeSlowamiKluczowymi,
23
    ModelZeStatusem,
24
    ModelZeSzczegolami,
25
    ModelZeZnakamiWydawniczymi,
26
    ModelZISBN,
27
    ModelZKonferencja,
28
    ModelZKwartylami,
29
    ModelZOpenAccess,
30
    ModelZPBN_UID,
31
    ModelZRokiem,
32
    ModelZWWW,
33
)
34
from bpp.models.fields import TupleField
2✔
35
from bpp.models.util import ModelZOpisemBibliograficznym
2✔
36
from bpp.util import FulltextSearchMixin
2✔
37

38

39
class RekordManager(FulltextSearchMixin, models.Manager):
2✔
40
    fts_field = "search_index"
2✔
41

42
    def get_for_model(self, model):
2✔
43
        pk = (ContentType.objects.get_for_model(model).pk, model.pk)
×
44
        return self.get(pk=pk)
×
45

46
    def prace_autora(self, autor):
2✔
47
        return self.filter(autorzy__autor=autor).distinct()
×
48

49
    def prace_autora_z_afiliowanych_jednostek(self, autor):
2✔
50
        """
51
        Funkcja zwraca prace danego autora, należące tylko i wyłącznie
52
        do jednostek skupiających pracowników, gdzie autor jest zaznaczony jako
53
        afiliowany.
54
        """
55
        return (
×
56
            self.prace_autora(autor)
57
            .filter(
58
                autorzy__autor=autor,
59
                autorzy__jednostka__skupia_pracownikow=True,
60
                autorzy__afiliuje=True,
61
            )
62
            .distinct()
63
        )
64

65
    def prace_autor_i_typ(self, autor, skrot):
2✔
66
        from bpp.models import Typ_Odpowiedzialnosci
×
67

68
        return (
×
69
            self.prace_autora(autor)
70
            .filter(
71
                autorzy__typ_odpowiedzialnosci_id=Typ_Odpowiedzialnosci.objects.get(
72
                    skrot=skrot
73
                ).pk
74
            )
75
            .distinct()
76
        )
77

78
    def prace_jednostki(self, jednostka, afiliowane=None):
2✔
79
        if afiliowane is None:
×
80
            return self.filter(
×
81
                autorzy__jednostka__pk__in=list(
82
                    jednostka.get_descendants(include_self=True).values_list(
83
                        "pk", flat=True
84
                    )
85
                )
86
            ).distinct()
87

88
        return self.filter(
×
89
            autorzy__jednostka__pk__in=list(
90
                jednostka.get_descendants(include_self=True).values_list(
91
                    "pk", flat=True
92
                )
93
            ),
94
            autorzy__afiliuje=afiliowane,
95
        ).distinct()
96

97
    def prace_wydzialu(self, wydzial, afiliowane=None):
2✔
98
        if afiliowane is None:
×
99
            return self.filter(autorzy__jednostka__wydzial=wydzial).distinct()
×
100

101
        return self.filter(
×
102
            autorzy__jednostka__wydzial=wydzial, autorzy__afiliuje=afiliowane
103
        ).distinct()
104

105
    def redaktorzy_z_jednostki(self, jednostka):
2✔
106
        from bpp.models import Typ_Odpowiedzialnosci
×
107

108
        return self.filter(
×
109
            autorzy__jednostka=jednostka,
110
            autorzy__typ_odpowiedzialnosci_id=Typ_Odpowiedzialnosci.objects.get(
111
                skrot="red."
112
            ).pk,
113
        ).distinct()
114

115
    def get_original(self, model):
2✔
116
        return self.get(pk=[ContentType.objects.get_for_model(model).pk, model.pk])
×
117

118
    def full_refresh(self):
2✔
119
        """Procedura odswieza opisy bibliograficzne dla wszystkich rekordów."""
UNCOV
120
        denorm.rebuildall("bpp.Wydawnictwo_Zwarte")
×
UNCOV
121
        denorm.rebuildall("bpp.Wydawnictwo_Ciagle")
×
UNCOV
122
        denorm.rebuildall("bpp.Patent")
×
UNCOV
123
        denorm.rebuildall("bpp.Praca_Doktorska")
×
UNCOV
124
        denorm.rebuildall("bpp.Praca_Habilitacyjna")
×
125

126

127
class _MyTaggableManager(_TaggableManager):
2✔
128
    def get_prefetch_queryset(self, instances, queryset=None):
2✔
129
        if queryset is not None:
×
130
            raise ValueError("Custom queryset can't be used for this lookup.")
×
131

132
        instance = instances[0]
×
133
        db = self._db or router.db_for_read(type(instance), instance=instance)
×
134

135
        fieldname = "rekord_id"
×
136
        fk = self.through._meta.get_field(fieldname)
×
137
        query = {
×
138
            "%s__%s__in"
139
            % (self.through.tag_relname(), fk.name): {
140
                obj._get_pk_val() for obj in instances
141
            }
142
        }
143
        join_table = self.through._meta.db_table
×
144
        source_col = fk.column
×
145
        connection = connections[db]
×
146
        qn = connection.ops.quote_name
×
147
        qs = (
×
148
            self.get_queryset(query)
149
            .using(db)
150
            .extra(
151
                select={
152
                    "_prefetch_related_val": "{}.{}".format(
153
                        qn(join_table), qn(source_col)
154
                    )
155
                }
156
            )
157
        )
158
        from operator import attrgetter
×
159

160
        rel_obj_attr = attrgetter("_prefetch_related_val")
×
161

162
        return (
×
163
            qs,
164
            rel_obj_attr,
165
            lambda obj: obj._get_pk_val(),
166
            False,
167
            self.prefetch_cache_name,
168
            False,
169
        )
170

171

172
class RekordBase(
2✔
173
    ModelPunktowanyBaza,
174
    ModelZOpisemBibliograficznym,
175
    ModelZRokiem,
176
    ModelZWWW,
177
    ModelZDOI,
178
    ModelZPBN_UID,
179
    ModelZeSzczegolami,
180
    ModelZeSlowamiKluczowymi,
181
    ModelRecenzowany,
182
    ModelZeZnakamiWydawniczymi,
183
    ModelZOpenAccess,
184
    ModelTypowany,
185
    ModelZCharakterem,
186
    ModelZKonferencja,
187
    ModelZISBN,
188
    ModelZeStatusem,
189
    ModelZKwartylami,
190
    models.Model,
191
):
192
    id = TupleField(models.IntegerField(), size=2, primary_key=True)
2✔
193

194
    tekst_przed_pierwszym_autorem = None
2✔
195
    tekst_po_ostatnim_autorze = None
2✔
196

197
    tytul_oryginalny = models.TextField()
2✔
198
    tytul = models.TextField()
2✔
199
    search_index = VectorField()
2✔
200

201
    zrodlo = models.ForeignKey("bpp.Zrodlo", null=True, on_delete=DO_NOTHING)
2✔
202
    wydawnictwo_nadrzedne = models.ForeignKey(
2✔
203
        "bpp.Wydawnictwo_Zwarte", null=True, on_delete=DO_NOTHING
204
    )
205
    slowa_kluczowe = TaggableManager(
2✔
206
        "Słowa kluczowe",
207
        through=SlowaKluczoweView,
208
        blank=True,
209
        manager=_MyTaggableManager,
210
    )
211

212
    wydawnictwo = models.TextField()
2✔
213

214
    adnotacje = models.TextField()
2✔
215
    ostatnio_zmieniony = models.DateTimeField()
2✔
216

217
    tytul_oryginalny_sort = models.TextField()
2✔
218

219
    liczba_autorow = models.SmallIntegerField()
2✔
220

221
    liczba_cytowan = models.SmallIntegerField()
2✔
222

223
    objects = RekordManager()
2✔
224

225
    opis_bibliograficzny_cache = models.TextField()
2✔
226
    opis_bibliograficzny_autorzy_cache = ArrayField(models.TextField())
2✔
227
    opis_bibliograficzny_zapisani_autorzy_cache = models.TextField()
2✔
228
    slug = models.TextField()
2✔
229

230
    strony = None
2✔
231
    nr_zeszytu = None
2✔
232
    tom = None
2✔
233

234
    jezyk_alt = None
2✔
235
    jezyk_orig = None
2✔
236

237
    # Skróty dla django-dsl
238

239
    django_dsl_shortcuts = {
2✔
240
        "charakter": "charakter_formalny__skrot",
241
        "typ_kbn": "typ_kbn__skrot",
242
        "typ_odpowiedzialnosci": "autorzy__typ_odpowiedzialnosci__skrot",
243
        "autor": "autorzy__autor_id",
244
        "jednostka": "autorzy__jednostka__pk",
245
        "wydzial": "autorzy__jednostka__wydzial__pk",
246
    }
247

248
    class Meta:
2✔
249
        abstract = True
2✔
250

251
    def __str__(self):
2✔
252
        return self.tytul_oryginalny
1✔
253

254
    @cached_property
2✔
255
    def content_type(self):
2✔
256
        return ContentType.objects.get(pk=self.id[0])
1✔
257

258
    @cached_property
2✔
259
    def describe_content_type(self):
2✔
260
        return ContentType.objects.get(pk=self.id[0]).model_class()._meta.verbose_name
×
261

262
    @cached_property
2✔
263
    def object_id(self):
2✔
264
        return self.id[1]
1✔
265

266
    @cached_property
2✔
267
    def original(self):
2✔
268
        return self.content_type.get_object_for_this_type(pk=self.object_id)
1✔
269

270
    @cached_property
2✔
271
    def js_safe_pk(self):
2✔
272
        return "%i_%i" % (self.pk[0], self.pk[1])
1✔
273

274
    @cached_property
2✔
275
    def form_post_pk(self):
2✔
276
        return "{%i,%i}" % (self.pk[0], self.pk[1])
1✔
277

278
    @cached_property
2✔
279
    def ma_punktacje_sloty(self):
2✔
280
        return (
×
281
            Cache_Punktacja_Autora.objects.filter(
282
                rekord_id=[self.id[0], self.id[1]]
283
            ).exists()
284
            or Cache_Punktacja_Dyscypliny.objects.filter(
285
                rekord_id=[self.id[0], self.id[1]]
286
            ).exists()
287
        )
288

289
    @cached_property
2✔
290
    def ma_odpiete_dyscypliny(self):
2✔
291
        return (
×
292
            self.original.autorzy_set.exclude(dyscyplina_naukowa=None)
293
            .exclude(przypieta=True)
294
            .exists()
295
        )
296

297
    @cached_property
2✔
298
    def punktacja_dyscypliny(self):
2✔
299
        return Cache_Punktacja_Dyscypliny.objects.filter(
×
300
            rekord_id=[self.id[0], self.id[1]]
301
        )
302

303
    @cached_property
2✔
304
    def punktacja_autora(self):
2✔
305
        return Cache_Punktacja_Autora.objects.filter(rekord_id=[self.id[0], self.id[1]])
×
306

307
    @cached_property
2✔
308
    def pierwszy_autor_afiliowany(self):
2✔
309
        """Zwraca pierwszego autora, afiliującego na jednostkę uczelni z tej pracy"""
310
        return self.autorzy.filter(afiliuje=True).order_by("kolejnosc").first()
×
311

312
    @cached_property
2✔
313
    def pierwsza_jednostka_afiliowana(self):
2✔
314
        """Zwraca pierwszego autora, afiliującego na jednostkę uczelni z tej pracy"""
315
        res = self.pierwszy_autor_afiliowany()
×
316
        if res is not None:
×
317
            return self.pierwszy_autor_afiliowany().jednostka
×
318

319
    def get_absolute_url(self):
2✔
320
        return reverse("bpp:browse_rekord", args=(self.pk[0], self.pk[1]))
1✔
321

322

323
class Rekord(RekordBase):
2✔
324
    class Meta:
2✔
325
        managed = False
2✔
326
        ordering = ["tytul_oryginalny_sort"]
2✔
327
        db_table = "bpp_rekord_mat"
2✔
328

329
    @cached_property
2✔
330
    def autorzy_set(self):
2✔
331
        return self.autorzy
×
332

333

334
class RekordView(RekordBase):
2✔
335
    class Meta:
2✔
336
        managed = False
2✔
337
        db_table = "bpp_rekord"
2✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc