0
# Framework Integrations
1
2
Database model mixins and query utilities for Django and SQLAlchemy frameworks, enabling seamless integration of PackageURL fields into web applications and ORM models. These integrations provide ready-to-use mixins that add PURL fields and related functionality to your models.
3
4
## Capabilities
5
6
### Django Integration
7
8
Django model mixins and query utilities for working with PackageURLs in Django applications.
9
10
```python { .api }
11
from packageurl.contrib.django.models import PackageURLMixin, PackageURLQuerySetMixin
12
from packageurl.contrib.django.utils import purl_to_lookups
13
14
class PackageURLMixin:
15
"""
16
Django model mixin providing PackageURL fields and methods.
17
18
Fields:
19
type (CharField): Package type field
20
namespace (CharField): Package namespace field
21
name (CharField): Package name field
22
version (CharField): Package version field
23
qualifiers (CharField): Package qualifiers field
24
subpath (CharField): Package subpath field
25
"""
26
27
def set_package_url(self, package_url):
28
"""
29
Set model fields from a PackageURL object or string.
30
31
Args:
32
package_url (PackageURL | str): PackageURL object or string to extract fields from
33
"""
34
35
def get_package_url(self):
36
"""
37
Get PackageURL object from model fields.
38
39
Returns:
40
PackageURL: PackageURL object constructed from model fields
41
"""
42
43
@property
44
def package_url(self):
45
"""
46
Get PackageURL as string property.
47
48
Returns:
49
str: PackageURL string representation
50
"""
51
52
class PackageURLQuerySetMixin:
53
"""
54
Django QuerySet mixin providing PackageURL filtering methods.
55
"""
56
57
def for_package_url(self, purl_str, encode=True, exact_match=False):
58
"""
59
Filter QuerySet based on a Package URL string.
60
61
Args:
62
purl_str (str): Package URL string to filter by
63
encode (bool): Whether to encode PURL components (default: True)
64
exact_match (bool): Whether to require exact match (default: False)
65
66
Returns:
67
QuerySet: Filtered queryset matching the PURL criteria
68
"""
69
70
def with_package_url(self):
71
"""
72
Return objects with Package URL defined.
73
74
Returns:
75
QuerySet: Objects that have both type and name fields populated
76
"""
77
78
def without_package_url(self):
79
"""
80
Return objects with empty Package URL.
81
82
Returns:
83
QuerySet: Objects with empty type or name fields
84
"""
85
86
def empty_package_url(self):
87
"""
88
Return objects with empty Package URL. Alias of without_package_url.
89
90
Returns:
91
QuerySet: Objects with empty Package URL
92
"""
93
94
def order_by_package_url(self):
95
"""
96
Order by Package URL fields.
97
98
Returns:
99
QuerySet: QuerySet ordered by type, namespace, name, version, qualifiers, subpath
100
"""
101
102
class PackageURLQuerySet(PackageURLQuerySetMixin, models.QuerySet):
103
"""
104
Django QuerySet that combines PackageURLQuerySetMixin with standard QuerySet.
105
Provides all PackageURL filtering methods on QuerySet objects.
106
"""
107
108
def purl_to_lookups(purl_str, encode=True, include_empty_fields=False):
109
"""
110
Convert PackageURL string to Django field lookups.
111
112
Args:
113
purl_str (str): PackageURL string to convert
114
encode (bool): Whether to encode components (default: True)
115
include_empty_fields (bool): Whether to include empty fields (default: False)
116
117
Returns:
118
dict: Dictionary of field lookups for Django queries
119
"""
120
121
def without_empty_values(input_dict):
122
"""
123
Return a new dict not including empty value entries from input_dict.
124
125
Args:
126
input_dict (dict): Dictionary to filter
127
128
Returns:
129
dict: Dictionary with empty values removed
130
131
Note:
132
None, empty string, empty list, and empty dict/set are cleaned.
133
0 and False values are kept.
134
"""
135
```
136
137
### SQLAlchemy Integration
138
139
SQLAlchemy declarative mixin providing PackageURL fields and methods for SQLAlchemy models.
140
141
```python { .api }
142
from packageurl.contrib.sqlalchemy.mixin import PackageURLMixin
143
144
class PackageURLMixin:
145
"""
146
SQLAlchemy declarative mixin providing PackageURL fields and methods.
147
148
Fields:
149
type (Mapped[str]): Package type column
150
namespace (Mapped[str]): Package namespace column
151
name (Mapped[str]): Package name column
152
version (Mapped[str]): Package version column
153
qualifiers (Mapped[str]): Package qualifiers column
154
subpath (Mapped[str]): Package subpath column
155
"""
156
157
def set_package_url(self, package_url):
158
"""
159
Set model fields from a PackageURL object or string.
160
161
Args:
162
package_url (PackageURL): PackageURL object to extract fields from
163
"""
164
165
def get_package_url(self):
166
"""
167
Get PackageURL object from model fields.
168
169
Returns:
170
PackageURL: PackageURL object constructed from model fields
171
"""
172
173
@property
174
def package_url(self):
175
"""
176
Get PackageURL as string property.
177
178
Returns:
179
str: PackageURL string representation
180
"""
181
```
182
183
### Django Filters
184
185
Django filter classes for PackageURL filtering in Django REST framework and similar applications.
186
187
```python { .api }
188
from packageurl.contrib.django.filters import PackageURLFilter
189
190
class PackageURLFilter(django_filters.CharFilter):
191
"""
192
Django filter for PackageURL fields.
193
194
Provides filtering capabilities for web APIs and admin interfaces.
195
Supports exact matching and empty Package URL filtering with special "EMPTY" value.
196
197
Attributes:
198
is_empty (str): Special value "EMPTY" to filter for empty Package URLs
199
exact_match_only (bool): Whether to require exact Package URL matching
200
help_text (str): Help text for the filter
201
"""
202
203
def __init__(self, exact_match_only=False, **kwargs):
204
"""
205
Initialize PackageURL filter.
206
207
Args:
208
exact_match_only (bool): Whether to match only exact Package URL strings
209
**kwargs: Additional filter arguments
210
"""
211
212
def filter(self, qs, value):
213
"""
214
Apply PackageURL filtering to QuerySet.
215
216
Args:
217
qs (QuerySet): QuerySet to filter
218
value (str): Filter value, or "EMPTY" for empty Package URLs
219
220
Returns:
221
QuerySet: Filtered QuerySet
222
"""
223
```
224
225
## Constants
226
227
```python { .api }
228
PACKAGE_URL_FIELDS = ("type", "namespace", "name", "version", "qualifiers", "subpath")
229
# Tuple of PackageURL field names used in Django models
230
```
231
232
## Usage Examples
233
234
### Django Model Integration
235
236
```python
237
from django.db import models
238
from packageurl.contrib.django.models import PackageURLMixin, PackageURLQuerySetMixin
239
from packageurl import PackageURL
240
241
class PackageQuerySet(models.QuerySet, PackageURLQuerySetMixin):
242
pass
243
244
class Package(models.Model, PackageURLMixin):
245
# Additional model fields
246
description = models.TextField(blank=True)
247
created_at = models.DateTimeField(auto_now_add=True)
248
249
objects = PackageQuerySet.as_manager()
250
251
def __str__(self):
252
return str(self.get_package_url())
253
254
# Usage
255
package = Package()
256
purl = PackageURL.from_string("pkg:pypi/django@3.2.0")
257
package.set_package_url(purl)
258
package.save()
259
260
# Query by PURL
261
packages = Package.objects.for_package_url("pkg:pypi/django@3.2.0")
262
django_packages = Package.objects.for_package_url("pkg:pypi/django", exact_match=False)
263
```
264
265
### SQLAlchemy Model Integration
266
267
```python
268
from sqlalchemy import Column, Integer, String, create_engine
269
from sqlalchemy.ext.declarative import declarative_base
270
from sqlalchemy.orm import sessionmaker
271
from packageurl.contrib.sqlalchemy.mixin import PackageURLMixin
272
from packageurl import PackageURL
273
274
Base = declarative_base()
275
276
class Package(Base, PackageURLMixin):
277
__tablename__ = 'packages'
278
279
id = Column(Integer, primary_key=True)
280
description = Column(String)
281
282
# Usage
283
engine = create_engine('sqlite:///packages.db')
284
Base.metadata.create_all(engine)
285
286
Session = sessionmaker(bind=engine)
287
session = Session()
288
289
package = Package()
290
purl = PackageURL.from_string("pkg:maven/org.springframework/spring-core@5.3.21")
291
package.set_package_url(purl)
292
session.add(package)
293
session.commit()
294
295
# Query
296
retrieved_purl = package.get_package_url()
297
print(retrieved_purl.to_string())
298
```
299
300
### Advanced Django Usage
301
302
```python
303
from packageurl.contrib.django.utils import purl_to_lookups
304
from packageurl import PackageURL
305
306
# Convert PURL to Django lookups
307
purl = PackageURL.from_string("pkg:npm/%40angular/core@12.0.0")
308
lookups = purl_to_lookups(purl)
309
310
# Use in manual queries
311
packages = Package.objects.filter(**lookups)
312
313
# Complex queries
314
maven_packages = Package.objects.filter(type='maven')
315
spring_packages = Package.objects.filter(
316
type='maven',
317
namespace__startswith='org.springframework'
318
)
319
```