mirror of
				https://gitlab.crans.org/bde/nk20
				synced 2025-11-04 09:12:11 +01:00 
			
		
		
		
	Rewrite script and add test
This commit is contained in:
		@@ -38,7 +38,7 @@ class Command(BaseCommand):
 | 
			
		||||
            required=False,
 | 
			
		||||
            help="""User will have their(s) wrapped generated,
 | 
			
		||||
            all = all users
 | 
			
		||||
            adh = all users who have a valid memberships to BDE during the BDE considered
 | 
			
		||||
            adh = all users who have a valid cd memberships to BDE during the BDE considered
 | 
			
		||||
            supersuser = all superusers
 | 
			
		||||
            custom user1,user2,... = a list of username,
 | 
			
		||||
            custom_id id1,id2,... = a list of user id""",
 | 
			
		||||
@@ -70,15 +70,7 @@ class Command(BaseCommand):
 | 
			
		||||
            dest='create',
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
    def handle(self, *args, **options):
 | 
			
		||||
        # useful string for output
 | 
			
		||||
        red = '\033[31;1m'
 | 
			
		||||
        yellow = '\033[33;1m'
 | 
			
		||||
        green = '\033[32;1m'
 | 
			
		||||
        abort = red + 'ABORT'
 | 
			
		||||
        warning = yellow + 'WARNING'
 | 
			
		||||
        success = green + 'SUCCESS'
 | 
			
		||||
 | 
			
		||||
    def handle(self, *args, **options): # NOQA
 | 
			
		||||
        # Traitement des paramètres
 | 
			
		||||
        verb = options['verbosity']
 | 
			
		||||
        bde = []
 | 
			
		||||
@@ -89,11 +81,11 @@ class Command(BaseCommand):
 | 
			
		||||
        if options['bde_id']:
 | 
			
		||||
            if bde:
 | 
			
		||||
                if verb >= 1:
 | 
			
		||||
                    print(warning)
 | 
			
		||||
                    print(yellow + 'You already defined bde with their name !')
 | 
			
		||||
                    self.stdout.write(self.style.WARNING(
 | 
			
		||||
                        "WARNING\nYou already defined bde with their name !"))
 | 
			
		||||
                if verb >= 0:
 | 
			
		||||
                    print(abort)
 | 
			
		||||
                return
 | 
			
		||||
                    self.stdout.write(self.style.ERROR("ABORT"))
 | 
			
		||||
                exit(1)
 | 
			
		||||
            bde_id = options['bde_id'].split(',')
 | 
			
		||||
            bde = [Bde.objects.get(pk=i) for i in bde_id]
 | 
			
		||||
 | 
			
		||||
@@ -113,11 +105,11 @@ class Command(BaseCommand):
 | 
			
		||||
                user = ['custom_id', [User.objects.get(pk=u) for u in user_id]]
 | 
			
		||||
            else:
 | 
			
		||||
                if verb >= 1:
 | 
			
		||||
                    print(warning)
 | 
			
		||||
                    print(yellow + 'You user option is not recognized')
 | 
			
		||||
                    self.sdtout.write(self.style.WARNING(
 | 
			
		||||
                        "WARNING\nYou user option is not recognized"))
 | 
			
		||||
                if verb >= 0:
 | 
			
		||||
                    print(abort)
 | 
			
		||||
                return
 | 
			
		||||
                    self.stdout.write(self.style.ERROR("ABORT"))
 | 
			
		||||
                exit(1)
 | 
			
		||||
 | 
			
		||||
        club = []
 | 
			
		||||
        if options['club']:
 | 
			
		||||
@@ -133,11 +125,11 @@ class Command(BaseCommand):
 | 
			
		||||
                club = ['custom_id', [Club.objects.get(pk=c) for c in club_id]]
 | 
			
		||||
            else:
 | 
			
		||||
                if verb >= 1:
 | 
			
		||||
                    print(warning)
 | 
			
		||||
                    print(yellow + 'You club option is not recognized')
 | 
			
		||||
                    self.stdout.write(self.style.WARNING(
 | 
			
		||||
                        "WARNING\nYou club option is not recognized"))
 | 
			
		||||
                if verb >= 0:
 | 
			
		||||
                    print(abort)
 | 
			
		||||
                return
 | 
			
		||||
                    self.stdout.write(self.style.ERROR("ABORT"))
 | 
			
		||||
                exit(1)
 | 
			
		||||
 | 
			
		||||
        change = options['change']
 | 
			
		||||
        create = options['create']
 | 
			
		||||
@@ -145,72 +137,75 @@ class Command(BaseCommand):
 | 
			
		||||
        # check if parameters are sufficient for generate wrapped with the desired option
 | 
			
		||||
        if not bde:
 | 
			
		||||
            if verb >= 1:
 | 
			
		||||
                print(warning)
 | 
			
		||||
                print(yellow + 'You have not selectionned a BDE !')
 | 
			
		||||
                self.stdout.write(self.style.WARNING(
 | 
			
		||||
                    "WARNING\nYou have not selectionned a BDE !"))
 | 
			
		||||
            if verb >= 0:
 | 
			
		||||
                print(abort)
 | 
			
		||||
            return
 | 
			
		||||
                self.stdout.write(self.style.ERROR("ABORT"))
 | 
			
		||||
            exit(1)
 | 
			
		||||
        if not (user or club):
 | 
			
		||||
            if verb >= 1:
 | 
			
		||||
                print(warning)
 | 
			
		||||
                print(yellow + 'No club or user selected !')
 | 
			
		||||
                self.stdout.write(self.style.WARNING(
 | 
			
		||||
                    "WARNING\nNo club or user selected !"))
 | 
			
		||||
            if verb >= 0:
 | 
			
		||||
                print(abort)
 | 
			
		||||
            return
 | 
			
		||||
                self.stdout.write(self.style.ERROR("ABORT"))
 | 
			
		||||
            exit(1)
 | 
			
		||||
 | 
			
		||||
        if verb >= 3:
 | 
			
		||||
            print('\033[1mOptions:\033[m')
 | 
			
		||||
            self.stdout.write("Options:")
 | 
			
		||||
            bde_str = ''
 | 
			
		||||
            for b in bde:
 | 
			
		||||
                bde_str += str(b)
 | 
			
		||||
            print('BDE: ' + bde_str)
 | 
			
		||||
                bde_str += str(b) + '\n'
 | 
			
		||||
            self.stdout.write("BDE: " + bde_str)
 | 
			
		||||
            if user:
 | 
			
		||||
                print('User: ' + user[0])
 | 
			
		||||
                self.stdout.write('User: ' + user[0])
 | 
			
		||||
            if club:
 | 
			
		||||
                print('Club: ' + club[0])
 | 
			
		||||
            print('change: ' + str(change))
 | 
			
		||||
            print('create: ' + str(create))
 | 
			
		||||
            print('')
 | 
			
		||||
                self.stdout.write('Club: ' + club[0])
 | 
			
		||||
            self.stdout.write('change: ' + str(change))
 | 
			
		||||
            self.stdout.write('create: ' + str(create) + '\n')
 | 
			
		||||
        if not (change or create):
 | 
			
		||||
            if verb >= 1:
 | 
			
		||||
                print(warning)
 | 
			
		||||
                print(yellow + 'change and create is set to false, none wrapped will be created')
 | 
			
		||||
                self.stdout.write(self.style.WARNING(
 | 
			
		||||
                    "WARNING\nchange and create is set to false, none wrapped will be created"))
 | 
			
		||||
            if verb >= 0:
 | 
			
		||||
                print(abort)
 | 
			
		||||
            return
 | 
			
		||||
                self.stdout.write(self.style.ERROR("ABORT"))
 | 
			
		||||
            exit(1)
 | 
			
		||||
        if verb >= 1 and change:
 | 
			
		||||
            print(warning)
 | 
			
		||||
            print(yellow + 'change is set to true, some wrapped may be replaced !')
 | 
			
		||||
            self.stdout.write(self.style.WARNING(
 | 
			
		||||
                "WARNING\nchange is set to true, some wrapped may be replaced !"))
 | 
			
		||||
        if verb >= 1 and not create:
 | 
			
		||||
            print(warning)
 | 
			
		||||
            print(yellow + 'create is set to false, wrapped will not be created !')
 | 
			
		||||
            self.stdout.write(self.style.WARNING(
 | 
			
		||||
                "WARNING\ncreate is set to false, wrapped will not be created !"))
 | 
			
		||||
        if verb >= 3 or change or not create:
 | 
			
		||||
            a = str(input('\033[mContinue ? (y/n) ')).lower()
 | 
			
		||||
            if a in ['n', 'no', 'non', '0']:
 | 
			
		||||
                if verb >= 0:
 | 
			
		||||
                    print(abort)
 | 
			
		||||
                return
 | 
			
		||||
                    self.stdout.write(self.style.ERROR("ABORT"))
 | 
			
		||||
                exit(1)
 | 
			
		||||
 | 
			
		||||
        note = self.convert_to_note(change, create, bde=bde, user=user, club=club, verb=verb)
 | 
			
		||||
        if verb >= 1:
 | 
			
		||||
            print("\033[32mUser and/or Club given has successfully convert in their note\033[m")
 | 
			
		||||
            self.stdout.write(self.style.SUCCESS(
 | 
			
		||||
                "User and/or Club given has successfully convert in their note"))
 | 
			
		||||
 | 
			
		||||
        global_data = self.global_data(bde, verb=verb)
 | 
			
		||||
        if verb >= 1:
 | 
			
		||||
            print("\033[32mGlobal data has been successfully generated\033[m")
 | 
			
		||||
            self.stdout.write(self.style.SUCCESS(
 | 
			
		||||
                "Global data has been successfully generated"))
 | 
			
		||||
 | 
			
		||||
        unique_data = self.unique_data(bde, note, global_data=global_data, verb=verb)
 | 
			
		||||
        if verb >= 1:
 | 
			
		||||
            print("\033[32mUnique data has been successfully generated\033[m")
 | 
			
		||||
            self.stdout.write(self.style.SUCCESS(
 | 
			
		||||
                "Unique data has been successfully generated"))
 | 
			
		||||
 | 
			
		||||
        self.make_wrapped(unique_data, note, bde, change, create, verb=verb)
 | 
			
		||||
        if verb >= 1:
 | 
			
		||||
            print(green + "The wrapped has been generated !")
 | 
			
		||||
            self.stdout.write(self.style.SUCCESS(
 | 
			
		||||
                "The wrapped has been generated !"))
 | 
			
		||||
        if verb >= 0:
 | 
			
		||||
            print(success)
 | 
			
		||||
            self.stdout.write(self.style.SUCCESS("SUCCESS"))
 | 
			
		||||
        exit(0)
 | 
			
		||||
 | 
			
		||||
        return
 | 
			
		||||
 | 
			
		||||
    def convert_to_note(self, change, create, bde=None, user=None, club=None, verb=1):
 | 
			
		||||
    def convert_to_note(self, change, create, bde=None, user=None, club=None, verb=1): # NOQA
 | 
			
		||||
        notes = []
 | 
			
		||||
        for b in bde:
 | 
			
		||||
            note_for_bde = Note.objects.filter(pk__lte=-1)
 | 
			
		||||
@@ -253,17 +248,17 @@ class Command(BaseCommand):
 | 
			
		||||
            note_for_bde = self.filter_note(b, note_for_bde, change, create, verb=verb)
 | 
			
		||||
            notes.append(note_for_bde)
 | 
			
		||||
            if verb >= 2:
 | 
			
		||||
                print("\033[m{nb} note selectionned for bde {bde}".format(nb=len(note_for_bde), bde=b.name))
 | 
			
		||||
                self.stdout.write(f"{len(note_for_bde)} note selectionned for bde {b.name}")
 | 
			
		||||
        return notes
 | 
			
		||||
 | 
			
		||||
    def global_data(self, bde, verb=1):
 | 
			
		||||
    def global_data(self, bde, verb=1): # NOQA
 | 
			
		||||
        data = {}
 | 
			
		||||
        for b in bde:
 | 
			
		||||
            if b.name == 'Rave Part[list]':
 | 
			
		||||
                if verb >= 2:
 | 
			
		||||
                    print("Begin to make global data")
 | 
			
		||||
                    self.stdout.write("Begin to make global data")
 | 
			
		||||
                if verb >= 3:
 | 
			
		||||
                    print('nb_transaction')
 | 
			
		||||
                    self.stdout.write("nb_transaction")
 | 
			
		||||
                # nb total de transactions
 | 
			
		||||
                data['nb_transaction'] = Transaction.objects.filter(
 | 
			
		||||
                    created_at__gte=b.date_start,
 | 
			
		||||
@@ -271,7 +266,7 @@ class Command(BaseCommand):
 | 
			
		||||
                    valid=True).count()
 | 
			
		||||
 | 
			
		||||
                if verb >= 3:
 | 
			
		||||
                    print('nb_vieux_con')
 | 
			
		||||
                    self.stdout.write("nb_vieux_con")
 | 
			
		||||
                # nb total de vielleux con·ne·s derrière le bar
 | 
			
		||||
                button_id = [2884, 2585]
 | 
			
		||||
                transactions = Transaction.objects.filter(
 | 
			
		||||
@@ -286,7 +281,7 @@ class Command(BaseCommand):
 | 
			
		||||
                data['nb_vieux_con'] = q
 | 
			
		||||
 | 
			
		||||
                if verb >= 3:
 | 
			
		||||
                    print('nb_soiree')
 | 
			
		||||
                    self.stdout.write("nb_soiree")
 | 
			
		||||
                # nb total de soirée
 | 
			
		||||
                a_type_id = [1, 2, 4, 5, 7, 10]
 | 
			
		||||
                data['nb_soiree'] = Activity.objects.filter(
 | 
			
		||||
@@ -296,7 +291,7 @@ class Command(BaseCommand):
 | 
			
		||||
                    activity_type__pk__in=a_type_id).count()
 | 
			
		||||
 | 
			
		||||
                if verb >= 3:
 | 
			
		||||
                    print('pots, nb_entree_pot')
 | 
			
		||||
                    self.stdout.write('pots, nb_entree_pot')
 | 
			
		||||
                # nb d'entrée totale aux pots
 | 
			
		||||
                pot_id = [1, 4, 10]
 | 
			
		||||
                pots = Activity.objects.filter(
 | 
			
		||||
@@ -310,7 +305,7 @@ class Command(BaseCommand):
 | 
			
		||||
                    data['nb_entree_pot'] += Entry.objects.filter(activity=pot).count()
 | 
			
		||||
 | 
			
		||||
                if verb >= 3:
 | 
			
		||||
                    print('top3_buttons')
 | 
			
		||||
                    self.stdout.write('top3_buttons')
 | 
			
		||||
                # top 3 des boutons les plus cliqués
 | 
			
		||||
                transactions = Transaction.objects.filter(
 | 
			
		||||
                    created_at__gte=b.date_start,
 | 
			
		||||
@@ -329,7 +324,7 @@ class Command(BaseCommand):
 | 
			
		||||
                data['top3_buttons'] = list(sorted(d.items(), key=lambda item: item[1], reverse=True))[:3]
 | 
			
		||||
 | 
			
		||||
                if verb >= 3:
 | 
			
		||||
                    print('class_conso_all')
 | 
			
		||||
                    self.stdout.write('class_conso_all')
 | 
			
		||||
                # le classement des plus gros consommateurs (BDE + club)
 | 
			
		||||
                transactions = Transaction.objects.filter(
 | 
			
		||||
                    created_at__gte=b.date_start,
 | 
			
		||||
@@ -348,7 +343,7 @@ class Command(BaseCommand):
 | 
			
		||||
                data['class_conso_all'] = dict(sorted(d.items(), key=lambda item: item[1], reverse=True))
 | 
			
		||||
 | 
			
		||||
                if verb >= 3:
 | 
			
		||||
                    print('class_conso_bde')
 | 
			
		||||
                    self.stdout.write('class_conso_bde')
 | 
			
		||||
                # le classement des plus gros consommateurs BDE
 | 
			
		||||
                transactions = Transaction.objects.filter(
 | 
			
		||||
                    created_at__gte=b.date_start,
 | 
			
		||||
@@ -368,11 +363,10 @@ class Command(BaseCommand):
 | 
			
		||||
 | 
			
		||||
            else:
 | 
			
		||||
                # make your wrapped or reuse previous wrapped
 | 
			
		||||
                raise NotImplementedError("The BDE: {bde_name} has not personalized wrapped, make it !"
 | 
			
		||||
                                          .format(bde_name=b.name))
 | 
			
		||||
                raise NotImplementedError(f"The BDE: {b.name} has not personalized wrapped, make it !")
 | 
			
		||||
        return data
 | 
			
		||||
 | 
			
		||||
    def unique_data(self, bde, note, global_data=None, verb=1):
 | 
			
		||||
    def unique_data(self, bde, note, global_data=None, verb=1): # NOQA
 | 
			
		||||
        data = []
 | 
			
		||||
        for i in range(len(bde)):
 | 
			
		||||
            data_bde = []
 | 
			
		||||
@@ -380,8 +374,7 @@ class Command(BaseCommand):
 | 
			
		||||
                if verb >= 3:
 | 
			
		||||
                    total = len(note[i])
 | 
			
		||||
                    current = 0
 | 
			
		||||
                    print('Make {nb} data for wrapped sponsored by {bde}'
 | 
			
		||||
                          .format(nb=total, bde=bde[i].name))
 | 
			
		||||
                    self.stdout.write(f"Make {total} data for wrapped sponsored by {bde[i].name}")
 | 
			
		||||
                for n in note[i]:
 | 
			
		||||
                    d = {}
 | 
			
		||||
                    if 'user' in n.__dir__():
 | 
			
		||||
@@ -542,12 +535,11 @@ class Command(BaseCommand):
 | 
			
		||||
                    data_bde.append(json.dumps(d))
 | 
			
		||||
                    if verb >= 3:
 | 
			
		||||
                        current += 1
 | 
			
		||||
                        print('\033[2K' + '({c}/{t})'.format(c=current, t=total) + '\033[1A')
 | 
			
		||||
                        self.stdout.write("\033[2K" + f"({current}/{total})" + "\033[1A")
 | 
			
		||||
 | 
			
		||||
            else:
 | 
			
		||||
                # make your wrapped or reuse previous wrapped
 | 
			
		||||
                raise NotImplementedError("The BDE: {bde_name} has not personalized wrapped, make it !"
 | 
			
		||||
                                          .format(bde_name=bde[i].name))
 | 
			
		||||
                raise NotImplementedError(f"The BDE: {bde[i].name} has not personalized wrapped, make it !")
 | 
			
		||||
            data.append(data_bde)
 | 
			
		||||
        return data
 | 
			
		||||
 | 
			
		||||
@@ -557,7 +549,7 @@ class Command(BaseCommand):
 | 
			
		||||
            total = 0
 | 
			
		||||
            for n in note:
 | 
			
		||||
                total += len(n)
 | 
			
		||||
            print('\033[mMake {nb} wrapped'.format(nb=total))
 | 
			
		||||
            self.stdout.write(f"Make {total} wrapped")
 | 
			
		||||
        for i in range(len(bde)):
 | 
			
		||||
            for j in range(len(note[i])):
 | 
			
		||||
                if create and not Wrapped.objects.filter(bde=bde[i], note=note[i][j]):
 | 
			
		||||
@@ -572,7 +564,7 @@ class Command(BaseCommand):
 | 
			
		||||
                    w.save()
 | 
			
		||||
                if verb >= 3:
 | 
			
		||||
                    current += 1
 | 
			
		||||
                    print('\033[2K' + '({c}/{t})'.format(c=current, t=total) + '\033[1A')
 | 
			
		||||
                    self.stdout.write("\033[2K" + f"({current}/{total})" + "\033[1A")
 | 
			
		||||
        return
 | 
			
		||||
 | 
			
		||||
    def filter_note(self, bde, note, change, create, verb=1):
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										0
									
								
								apps/wrapped/tests/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								apps/wrapped/tests/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										91
									
								
								apps/wrapped/tests/test_wrapped.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										91
									
								
								apps/wrapped/tests/test_wrapped.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,91 @@
 | 
			
		||||
# Copyright (C) 2018-2025 by BDE ENS Paris-Saclay
 | 
			
		||||
# SPDX-License-Identifier: GPL-3.0-or-later
 | 
			
		||||
 | 
			
		||||
from datetime import timedelta
 | 
			
		||||
 | 
			
		||||
from api.tests import TestAPI
 | 
			
		||||
from django.contrib.auth.models import User
 | 
			
		||||
from django.test import TestCase
 | 
			
		||||
from django.urls import reverse
 | 
			
		||||
from django.utils import timezone
 | 
			
		||||
 | 
			
		||||
from ..api.views import WrappedViewSet, BdeViewSet
 | 
			
		||||
from ..models import Bde, Wrapped
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class TestWrapped(TestCase):
 | 
			
		||||
    """
 | 
			
		||||
    Test activities
 | 
			
		||||
    """
 | 
			
		||||
    fixtures = ('initial',)
 | 
			
		||||
 | 
			
		||||
    def setUp(self):
 | 
			
		||||
        self.user = User.objects.create_superuser(
 | 
			
		||||
            username="admintoto",
 | 
			
		||||
            password="tototototo",
 | 
			
		||||
            email="toto@example.com"
 | 
			
		||||
        )
 | 
			
		||||
        self.client.force_login(self.user)
 | 
			
		||||
 | 
			
		||||
        sess = self.client.session
 | 
			
		||||
        sess["permission_mask"] = 42
 | 
			
		||||
        sess.save()
 | 
			
		||||
 | 
			
		||||
        self.bde = Bde.objects.create(
 | 
			
		||||
            name="The best BDE",
 | 
			
		||||
            date_start=timezone.now() - timedelta(days=365),
 | 
			
		||||
            date_end=timezone.now(),
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
        self.wrapped = Wrapped.objects.create(
 | 
			
		||||
            generated=True,
 | 
			
		||||
            public=False,
 | 
			
		||||
            bde=self.bde,
 | 
			
		||||
            note=self.user.note,
 | 
			
		||||
            data_json="{}",
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
    def test_wrapped_list(self):
 | 
			
		||||
        """
 | 
			
		||||
        Display the list of all wrapped
 | 
			
		||||
        """
 | 
			
		||||
        response = self.client.get(reverse("wrapped:wrapped_list"))
 | 
			
		||||
        self.assertEqual(response.status_code, 200)
 | 
			
		||||
 | 
			
		||||
    def test_wrapped_detail(self):
 | 
			
		||||
        """
 | 
			
		||||
        Display the detail of an wrapped
 | 
			
		||||
        """
 | 
			
		||||
        response = self.client.get(reverse("wrapped:wrapped_detail", args=(self.wrapped.pk,)))
 | 
			
		||||
        self.assertEqual(response.status_code, 200)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class TestWrappedAPI(TestAPI):
 | 
			
		||||
    def setUp(self) -> None:
 | 
			
		||||
        super().setUp()
 | 
			
		||||
 | 
			
		||||
        self.bde = Bde.objects.create(
 | 
			
		||||
            name="The best BDE",
 | 
			
		||||
            date_start=timezone.now() - timedelta(days=365),
 | 
			
		||||
            date_end=timezone.now(),
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
        self.wrapped = Wrapped.objects.create(
 | 
			
		||||
            generated=True,
 | 
			
		||||
            public=False,
 | 
			
		||||
            bde=self.bde,
 | 
			
		||||
            note=self.user.note,
 | 
			
		||||
            data_json="{}",
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
    def test_bde_api(self):
 | 
			
		||||
        """
 | 
			
		||||
        Load Bde API page and test all filters and permissions
 | 
			
		||||
        """
 | 
			
		||||
        self.check_viewset(BdeViewSet, "/api/wrapped/bde/")
 | 
			
		||||
 | 
			
		||||
    def test_wrapped_api(self):
 | 
			
		||||
        """
 | 
			
		||||
        Load Wrapped API page and test all filters and permissions
 | 
			
		||||
        """
 | 
			
		||||
        self.check_viewset(WrappedViewSet, "/api/wrapped/wrapped/")
 | 
			
		||||
		Reference in New Issue
	
	Block a user