1👍
✅
I decided to go with a custom field and override post(). Would appreciate comments/edits if there’s a better way.
forms.py
import uuid
from django.core.exceptions import ValidationError
MAX_UUIDS = 10
class UUIDArrayField(forms.Field):
""" Custom field representing an array of up to MAX_UUIDS uuid4 strings """
def clean(self, value):
if type(value) != type([]):
raise ValidationError(self.error_messages['not_a_list'])
if len(value) > MAX_UUIDS:
raise ValidationError(self.error_messages['too_many_values'])
try:
for v in value:
print(v)
uuid.UUID(v, version=4) # ValueError if not a valid uuid4
return value
except:
raise ValidationError(self.error_messages['invalid_uuid'])
class ObjectMultiDeleteForm(forms.Form):
""" form to delete multiple products """
uuids = UUIDArrayField(
error_messages = {
'not_a_list': _("A data type other than list was supplied."),
'too_many_values': _("The list of values exceeds the maximum allowed."),
'invalid_uuid': _("An invalid identifier was specified."),
})
views.py
from django.shortcuts import redirect
class ObjectMultiDelete(FormView):
""" Deletes object instances from a list of their uuids """
http_method_names = ['post',] #only accept POST requests
success_url = reverse_lazy("objectlist")
success_message = "%(message)s"
form_class = ProductMultiDeleteForm
def dispatch(self, request, *args, **kwargs):
#access control goes here
return super(ObjectMultiDelete, self).dispatch(request, *args, **kwargs)
def get_success_message(self, cleaned_data):
return self.success_message % dict(
message = _("The specified objects were successfully deleted."),
)
def post(self, request, *args, **kwargs):
post_data = request.POST.copy() #request.POST is immutable
#because you can't name a form field 'uuids[]', but that's what you get when posting an array
post_data['uuids'] = post_data.pop('uuids[]')
form = ObjectMultiDeleteForm()
form.data = post_data #bind form
form.is_bound = True
if form.is_valid():
objects = Object.objects.filter(access_control_here)\
.filter(uuid__in=form.cleaned_data['uuids'])
objects.delete()
return redirect(self.success_url)
else:
#handle invalid form how you want
0👍
In that case you’re probably be best of with writing a small model that you can include at another place:
class UUIDItem(models.Model):
request = models.PositiveIntegerField()
uuid = models.UUID()
which you can easily put in relation with another model:
class UUIDContainer(models.Model):
request = AutoField()
@classmethod
def add(self, uuid):
if isinstance(uuid, list):
for id in uuids:
UUIDItem.objects.filter(request=self.request, uuid=id).create()
else:
UUIDItem.objects.filter(request=self.request, uuid=uuid).create()
uuids = models.ForeignKey(
UUIDRequest,
on_delete=model.CASCADE,
limit_choices_to={'request': self.request})
With this level of abstraction you can just easily list, modify and add UUID’s to an existing request, or create a different “storage”
l = UUIDList()
l.add(your_uuids)
l.id # will print some id
UUIDItem.objects.filter(request=l.request).all()
Eh voila. Handles your list of UUID’s.
- With uwsgi deployed Django, part css and js can get, others can not
- Django SECRET_KEY unique for same project on each workstation?
- Getting model instance by variable model name and pk
Source:stackexchange.com