forked from CGM_Public/pretix_original
Add sales channels (#1103)
- [x] Data model - [x] Enforce constraint - [x] Filter order list - [x] Set channel on created order - [x] Products API - [x] Order API - [x] Tests - [x] Filter reports - [x] Resellers - [ ] deploy plugins - [ ] posbackend - [ ] resellers - [ ] reports - [x] Ticketlayouts - [x] Support in pretixPOS
This commit is contained in:
94
src/pretix/base/models/fields.py
Normal file
94
src/pretix/base/models/fields.py
Normal file
@@ -0,0 +1,94 @@
|
||||
from django.core import exceptions
|
||||
from django.db.models import TextField, lookups as builtin_lookups
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
from rest_framework import serializers
|
||||
from rest_framework.exceptions import ValidationError
|
||||
|
||||
DELIMITER = "\x1F"
|
||||
|
||||
|
||||
class MultiStringField(TextField):
|
||||
default_error_messages = {
|
||||
'delimiter_found': _('No value can contain the delimiter character.')
|
||||
}
|
||||
|
||||
def __init__(self, verbose_name=None, name=None, **kwargs):
|
||||
super().__init__(verbose_name, name, **kwargs)
|
||||
|
||||
def deconstruct(self):
|
||||
name, path, args, kwargs = super().deconstruct()
|
||||
return name, path, args, kwargs
|
||||
|
||||
def to_python(self, value):
|
||||
if isinstance(value, (list, tuple)):
|
||||
return value
|
||||
elif value:
|
||||
return [v for v in value.split(DELIMITER) if v]
|
||||
else:
|
||||
return []
|
||||
|
||||
def get_prep_value(self, value):
|
||||
if isinstance(value, (list, tuple)):
|
||||
return DELIMITER + DELIMITER.join(value) + DELIMITER
|
||||
elif value is None:
|
||||
return ""
|
||||
raise TypeError("Invalid data type passed.")
|
||||
|
||||
def get_prep_lookup(self, lookup_type, value): # NOQA
|
||||
raise TypeError('Lookups on multi strings are currently not supported.')
|
||||
|
||||
def from_db_value(self, value, expression, connection, context):
|
||||
if value:
|
||||
return [v for v in value.split(DELIMITER) if v]
|
||||
else:
|
||||
return []
|
||||
|
||||
def validate(self, value, model_instance):
|
||||
super().validate(value, model_instance)
|
||||
for l in value:
|
||||
if DELIMITER in l:
|
||||
raise exceptions.ValidationError(
|
||||
self.error_messages['delimiter_found'],
|
||||
code='delimiter_found',
|
||||
)
|
||||
|
||||
def get_lookup(self, lookup_name):
|
||||
if lookup_name == 'contains':
|
||||
return MultiStringContains
|
||||
elif lookup_name == 'icontains':
|
||||
return MultiStringIContains
|
||||
raise NotImplementedError(
|
||||
"Lookup '{}' doesn't work with MultiStringField".format(lookup_name),
|
||||
)
|
||||
|
||||
|
||||
class MultiStringContains(builtin_lookups.Contains):
|
||||
def process_rhs(self, qn, connection):
|
||||
sql, params = super().process_rhs(qn, connection)
|
||||
params[0] = "%" + DELIMITER + params[0][1:-1] + DELIMITER + "%"
|
||||
return sql, params
|
||||
|
||||
|
||||
class MultiStringIContains(builtin_lookups.IContains):
|
||||
def process_rhs(self, qn, connection):
|
||||
sql, params = super().process_rhs(qn, connection)
|
||||
params[0] = "%" + DELIMITER + params[0][1:-1] + DELIMITER + "%"
|
||||
return sql, params
|
||||
|
||||
|
||||
class MultiStringSerializer(serializers.Field):
|
||||
def __init__(self, **kwargs):
|
||||
self.allow_blank = kwargs.pop('allow_blank', False)
|
||||
super().__init__(**kwargs)
|
||||
|
||||
def to_representation(self, value):
|
||||
return value
|
||||
|
||||
def to_internal_value(self, data):
|
||||
if isinstance(data, list):
|
||||
return data
|
||||
else:
|
||||
raise ValidationError('Invalid data type.')
|
||||
|
||||
|
||||
serializers.ModelSerializer.serializer_field_mapping[MultiStringField] = MultiStringSerializer
|
||||
Reference in New Issue
Block a user