In debug mode looks like, create a new app using your idea about a possible mistake in setting without django-storages works perfectly but with this one crash with the exception below. Trying to fix it but does not look clear which line in django-storages has the issue.
SuspiciousFileOperation at /admin/dummyapp/country/add/Detected path traversal attempt in '/home/joalbert/Documents/test/dummy/media/country/images/us_bP4iy1J.png' Request Method: POST Request URL: http://localhost:8000/admin/dummyapp/country/add/ Django Version: 3.2.12 Exception Type: SuspiciousFileOperation Exception Value: Detected path traversal attempt in '/home/joalbert/Documents/test/dummy/media/country/images/us_bP4iy1J.png' Exception Location: /home/joalbert/.local/lib/python3.8/site-packages/django/core/files/utils.py, line 18, in validate_file_name Python Executable: /usr/bin/python3 Python Version: 3.8.10 Python Path: ['/home/joalbert/Documents/test/dummy', '/usr/lib/python38.zip', '/usr/lib/python3.8', '/usr/lib/python3.8/lib-dynload', '/home/joalbert/.local/lib/python3.8/site-packages', '/usr/local/lib/python3.8/dist-packages', '/usr/lib/python3/dist-packages'] Environment: Request Method: POST Request URL: http://localhost:8000/admin/dummyapp/country/add/ Django Version: 3.2.12 Python Version: 3.8.10 Installed Applications: ['django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', * 'storages',* 'dummyapp'] Installed Middleware: ['django.middleware.security.SecurityMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.common.CommonMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware'] Traceback (most recent call last): File "/home/joalbert/.local/lib/python3.8/site-packages/django/core/handlers/exception.py", line 47, in inner response = get_response(request) File "/home/joalbert/.local/lib/python3.8/site-packages/django/core/handlers/base.py", line 181, in _get_response response = wrapped_callback(request, *callback_args, **callback_kwargs) File "/home/joalbert/.local/lib/python3.8/site-packages/django/contrib/admin/options.py", line 616, in wrapper return self.admin_site.admin_view(view)(*args, **kwargs) File "/home/joalbert/.local/lib/python3.8/site-packages/django/utils/decorators.py", line 130, in _wrapped_view response = view_func(request, *args, **kwargs) File "/home/joalbert/.local/lib/python3.8/site-packages/django/views/decorators/cache.py", line 44, in _wrapped_view_func response = view_func(request, *args, **kwargs) File "/home/joalbert/.local/lib/python3.8/site-packages/django/contrib/admin/sites.py", line 232, in inner return view(request, *args, **kwargs) File "/home/joalbert/.local/lib/python3.8/site-packages/django/contrib/admin/options.py", line 1657, in add_view return self.changeform_view(request, None, form_url, extra_context) File "/home/joalbert/.local/lib/python3.8/site-packages/django/utils/decorators.py", line 43, in _wrapper return bound_method(*args, **kwargs) File "/home/joalbert/.local/lib/python3.8/site-packages/django/utils/decorators.py", line 130, in _wrapped_view response = view_func(request, *args, **kwargs) File "/home/joalbert/.local/lib/python3.8/site-packages/django/contrib/admin/options.py", line 1540, in changeform_view return self._changeform_view(request, object_id, form_url, extra_context) File "/home/joalbert/.local/lib/python3.8/site-packages/django/contrib/admin/options.py", line 1586, in _changeform_view self.save_model(request, new_object, form, not add) File "/home/joalbert/.local/lib/python3.8/site-packages/django/contrib/admin/options.py", line 1099, in save_model obj.save() File "/home/joalbert/.local/lib/python3.8/site-packages/django/db/models/base.py", line 739, in save self.save_base(using=using, force_insert=force_insert, File "/home/joalbert/.local/lib/python3.8/site-packages/django/db/models/base.py", line 776, in save_base updated = self._save_table( File "/home/joalbert/.local/lib/python3.8/site-packages/django/db/models/base.py", line 881, in _save_table results = self._do_insert(cls._base_manager, using, fields, returning_fields, raw) File "/home/joalbert/.local/lib/python3.8/site-packages/django/db/models/base.py", line 919, in _do_insert return manager._insert( File "/home/joalbert/.local/lib/python3.8/site-packages/django/db/models/manager.py", line 85, in manager_method return getattr(self.get_queryset(), name)(*args, **kwargs) File "/home/joalbert/.local/lib/python3.8/site-packages/django/db/models/query.py", line 1270, in _insert return query.get_compiler(using=using).execute_sql(returning_fields) File "/home/joalbert/.local/lib/python3.8/site-packages/django/db/models/sql/compiler.py", line 1415, in execute_sql for sql, params in self.as_sql(): File "/home/joalbert/.local/lib/python3.8/site-packages/django/db/models/sql/compiler.py", line 1358, in as_sql value_rows = [ File "/home/joalbert/.local/lib/python3.8/site-packages/django/db/models/sql/compiler.py", line 1359, in <listcomp> [self.prepare_value(field, self.pre_save_val(field, obj)) for field in fields] File "/home/joalbert/.local/lib/python3.8/site-packages/django/db/models/sql/compiler.py", line 1359, in <listcomp> [self.prepare_value(field, self.pre_save_val(field, obj)) for field in fields] File "/home/joalbert/.local/lib/python3.8/site-packages/django/db/models/sql/compiler.py", line 1310, in pre_save_val return field.pre_save(obj, add=True) File "/home/joalbert/.local/lib/python3.8/site-packages/django/db/models/fields/files.py", line 302, in pre_save file.save(file.name, file.file, save=False) File "/home/joalbert/.local/lib/python3.8/site-packages/django/db/models/fields/files.py", line 89, in save self.name = self.storage.save(name, content, max_length=self.field.max_length) File "/home/joalbert/.local/lib/python3.8/site-packages/django/core/files/storage.py", line 56, in save validate_file_name(name, allow_relative_path=True) File "/home/joalbert/.local/lib/python3.8/site-packages/django/core/files/utils.py", line 18, in validate_file_name raise SuspiciousFileOperation( Exception Type: SuspiciousFileOperation at /admin/dummyapp/country/add/ Exception Value: Detected path traversal attempt in '/home/joalbert/Documents/test/dummy/media/country/images/us_bP4iy1J.png' Server time: Fri, 04 Feb 2022 19:41:15 +0000 *Setting* SettingsUsing settings module dummy.settings Setting Value ABSOLUTE_URL_OVERRIDES {} ADMINS [] ALLOWED_HOSTS ['localhost'] APPEND_SLASH True AUTHENTICATION_BACKENDS ['django.contrib.auth.backends.ModelBackend'] AUTH_PASSWORD_VALIDATORS '********************' AUTH_USER_MODEL 'auth.User' BASE_DIR PosixPath('/home/joalbert/Documents/test/dummy') CACHES {'default': {'BACKEND': 'django.core.cache.backends.locmem.LocMemCache'}} CACHE_MIDDLEWARE_ALIAS 'default' CACHE_MIDDLEWARE_KEY_PREFIX '********************' CACHE_MIDDLEWARE_SECONDS 600 CSRF_COOKIE_AGE 31449600 CSRF_COOKIE_DOMAIN None CSRF_COOKIE_HTTPONLY False CSRF_COOKIE_NAME 'csrftoken' CSRF_COOKIE_PATH '/' CSRF_COOKIE_SAMESITE 'Lax' CSRF_COOKIE_SECURE False CSRF_FAILURE_VIEW 'django.views.csrf.csrf_failure' CSRF_HEADER_NAME 'HTTP_X_CSRFTOKEN' CSRF_TRUSTED_ORIGINS [] CSRF_USE_SESSIONS False DATABASES {'default': {'ATOMIC_REQUESTS': False, 'AUTOCOMMIT': True, 'CONN_MAX_AGE': 0, 'ENGINE': 'django.db.backends.sqlite3', 'HOST': '', 'NAME': PosixPath('/home/joalbert/Documents/test/dummy/db.sqlite3'), 'OPTIONS': {}, 'PASSWORD': '********************', 'PORT': '', 'TEST': {'CHARSET': None, 'COLLATION': None, 'MIGRATE': True, 'MIRROR': None, 'NAME': None}, 'TIME_ZONE': None, 'USER': ''}} DATABASE_ROUTERS [] DATA_UPLOAD_MAX_MEMORY_SIZE 52428800 DATA_UPLOAD_MAX_NUMBER_FIELDS 1000 DATETIME_FORMAT 'N j, Y, P' DATETIME_INPUT_FORMATS ['%Y-%m-%d %H:%M:%S', '%Y-%m-%d %H:%M:%S.%f', '%Y-%m-%d %H:%M', '%m/%d/%Y %H:%M:%S', '%m/%d/%Y %H:%M:%S.%f', '%m/%d/%Y %H:%M', '%m/%d/%y %H:%M:%S', '%m/%d/%y %H:%M:%S.%f', '%m/%d/%y %H:%M'] DATE_FORMAT 'N j, Y' DATE_INPUT_FORMATS ['%Y-%m-%d', '%m/%d/%Y', '%m/%d/%y', '%b %d %Y', '%b %d, %Y', '%d %b %Y', '%d %b, %Y', '%B %d %Y', '%B %d, %Y', '%d %B %Y', '%d %B, %Y'] DEBUG True DEBUG_PROPAGATE_EXCEPTIONS False DECIMAL_SEPARATOR '.' DEFAULT_AUTO_FIELD 'django.db.models.BigAutoField' DEFAULT_CHARSET 'utf-8' DEFAULT_EXCEPTION_REPORTER 'django.views.debug.ExceptionReporter' DEFAULT_EXCEPTION_REPORTER_FILTER 'django.views.debug.SafeExceptionReporterFilter' *DEFAULT_FILE_STORAGE'storages.backends.dropbox.DropBoxStorage'* DEFAULT_FROM_EMAIL 'webmaster@localhost' DEFAULT_HASHING_ALGORITHM 'sha256' DEFAULT_INDEX_TABLESPACE '' DEFAULT_TABLESPACE '' DISALLOWED_USER_AGENTS [] DROPBOX_OAUTH2_TOKEN '********************' DROPBOX_ROOT_PATH 'media' EMAIL_BACKEND 'django.core.mail.backends.smtp.EmailBackend' EMAIL_HOST 'localhost' EMAIL_HOST_PASSWORD '********************' EMAIL_HOST_USER '' EMAIL_PORT 25 EMAIL_SSL_CERTFILE None EMAIL_SSL_KEYFILE '********************' EMAIL_SUBJECT_PREFIX '[Django] ' EMAIL_TIMEOUT None EMAIL_USE_LOCALTIME False EMAIL_USE_SSL False EMAIL_USE_TLS False FILE_UPLOAD_DIRECTORY_PERMISSIONS None FILE_UPLOAD_HANDLERS ['django.core.files.uploadhandler.MemoryFileUploadHandler', 'django.core.files.uploadhandler.TemporaryFileUploadHandler'] FILE_UPLOAD_MAX_MEMORY_SIZE 2621440 FILE_UPLOAD_PERMISSIONS 420 FILE_UPLOAD_TEMP_DIR None FIRST_DAY_OF_WEEK 0 FIXTURE_DIRS [] FORCE_SCRIPT_NAME None FORMAT_MODULE_PATH None FORM_RENDERER 'django.forms.renderers.DjangoTemplates' IGNORABLE_404_URLS [] INSTALLED_APPS ['django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'storages', 'dummyapp'] INTERNAL_IPS [] LANGUAGES [('af', 'Afrikaans'), ('ar', 'Arabic'), ('ar-dz', 'Algerian Arabic'), ('ast', 'Asturian'), ('az', 'Azerbaijani'), ('bg', 'Bulgarian'), ('be', 'Belarusian'), ('bn', 'Bengali'), ('br', 'Breton'), ('bs', 'Bosnian'), ('ca', 'Catalan'), ('cs', 'Czech'), ('cy', 'Welsh'), ('da', 'Danish'), ('de', 'German'), ('dsb', 'Lower Sorbian'), ('el', 'Greek'), ('en', 'English'), ('en-au', 'Australian English'), ('en-gb', 'British English'), ('eo', 'Esperanto'), ('es', 'Spanish'), ('es-ar', 'Argentinian Spanish'), ('es-co', 'Colombian Spanish'), ('es-mx', 'Mexican Spanish'), ('es-ni', 'Nicaraguan Spanish'), ('es-ve', 'Venezuelan Spanish'), ('et', 'Estonian'), ('eu', 'Basque'), ('fa', 'Persian'), ('fi', 'Finnish'), ('fr', 'French'), ('fy', 'Frisian'), ('ga', 'Irish'), ('gd', 'Scottish Gaelic'), ('gl', 'Galician'), ('he', 'Hebrew'), ('hi', 'Hindi'), ('hr', 'Croatian'), ('hsb', 'Upper Sorbian'), ('hu', 'Hungarian'), ('hy', 'Armenian'), ('ia', 'Interlingua'), ('id', 'Indonesian'), ('ig', 'Igbo'), ('io', 'Ido'), ('is', 'Icelandic'), ('it', 'Italian'), ('ja', 'Japanese'), ('ka', 'Georgian'), ('kab', 'Kabyle'), ('kk', 'Kazakh'), ('km', 'Khmer'), ('kn', 'Kannada'), ('ko', 'Korean'), ('ky', 'Kyrgyz'), ('lb', 'Luxembourgish'), ('lt', 'Lithuanian'), ('lv', 'Latvian'), ('mk', 'Macedonian'), ('ml', 'Malayalam'), ('mn', 'Mongolian'), ('mr', 'Marathi'), ('my', 'Burmese'), ('nb', 'Norwegian Bokmål'), ('ne', 'Nepali'), ('nl', 'Dutch'), ('nn', 'Norwegian Nynorsk'), ('os', 'Ossetic'), ('pa', 'Punjabi'), ('pl', 'Polish'), ('pt', 'Portuguese'), ('pt-br', 'Brazilian Portuguese'), ('ro', 'Romanian'), ('ru', 'Russian'), ('sk', 'Slovak'), ('sl', 'Slovenian'), ('sq', 'Albanian'), ('sr', 'Serbian'), ('sr-latn', 'Serbian Latin'), ('sv', 'Swedish'), ('sw', 'Swahili'), ('ta', 'Tamil'), ('te', 'Telugu'), ('tg', 'Tajik'), ('th', 'Thai'), ('tk', 'Turkmen'), ('tr', 'Turkish'), ('tt', 'Tatar'), ('udm', 'Udmurt'), ('uk', 'Ukrainian'), ('ur', 'Urdu'), ('uz', 'Uzbek'), ('vi', 'Vietnamese'), ('zh-hans', 'Simplified Chinese'), ('zh-hant', 'Traditional Chinese')] LANGUAGES_BIDI ['he', 'ar', 'ar-dz', 'fa', 'ur'] LANGUAGE_CODE 'en-us' LANGUAGE_COOKIE_AGE None LANGUAGE_COOKIE_DOMAIN None LANGUAGE_COOKIE_HTTPONLY False LANGUAGE_COOKIE_NAME 'django_language' LANGUAGE_COOKIE_PATH '/' LANGUAGE_COOKIE_SAMESITE None LANGUAGE_COOKIE_SECURE False LOCALE_PATHS [] LOGGING {} LOGGING_CONFIG 'logging.config.dictConfig' LOGIN_REDIRECT_URL '/accounts/profile/' LOGIN_URL '/accounts/login/' LOGOUT_REDIRECT_URL None MANAGERS [] MEDIA_ROOT '/home/joalbert/Documents/test/dummy/media' MEDIA_URL '/media/' MESSAGE_STORAGE 'django.contrib.messages.storage.fallback.FallbackStorage' MIDDLEWARE ['django.middleware.security.SecurityMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.common.CommonMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware'] MIGRATION_MODULES {} MONTH_DAY_FORMAT 'F j' NUMBER_GROUPING 0 PASSWORD_HASHERS '********************' PASSWORD_RESET_TIMEOUT '********************' PASSWORD_RESET_TIMEOUT_DAYS '********************' PREPEND_WWW False ROOT_URLCONF 'dummy.urls' SECRET_KEY '********************' SECURE_BROWSER_XSS_FILTER False SECURE_CONTENT_TYPE_NOSNIFF True SECURE_HSTS_INCLUDE_SUBDOMAINS False SECURE_HSTS_PRELOAD False SECURE_HSTS_SECONDS 0 SECURE_PROXY_SSL_HEADER None SECURE_REDIRECT_EXEMPT [] SECURE_REFERRER_POLICY 'same-origin' SECURE_SSL_HOST None SECURE_SSL_REDIRECT False SERVER_EMAIL 'root@localhost' SESSION_CACHE_ALIAS 'default' SESSION_COOKIE_AGE 1209600 SESSION_COOKIE_DOMAIN None SESSION_COOKIE_HTTPONLY True SESSION_COOKIE_NAME 'sessionid' SESSION_COOKIE_PATH '/' SESSION_COOKIE_SAMESITE 'Lax' SESSION_COOKIE_SECURE False SESSION_ENGINE 'django.contrib.sessions.backends.db' SESSION_EXPIRE_AT_BROWSER_CLOSE False SESSION_FILE_PATH None SESSION_SAVE_EVERY_REQUEST False SESSION_SERIALIZER 'django.contrib.sessions.serializers.JSONSerializer' SETTINGS_MODULE 'dummy.settings' SHORT_DATETIME_FORMAT 'm/d/Y P' SHORT_DATE_FORMAT 'm/d/Y' SIGNING_BACKEND 'django.core.signing.TimestampSigner' SILENCED_SYSTEM_CHECKS [] STATICFILES_DIRS [] STATICFILES_FINDERS ['django.contrib.staticfiles.finders.FileSystemFinder', 'django.contrib.staticfiles.finders.AppDirectoriesFinder'] STATICFILES_STORAGE 'django.contrib.staticfiles.storage.StaticFilesStorage' STATIC_ROOT None STATIC_URL '/static/' TEMPLATES [{'APP_DIRS': True, 'BACKEND': 'django.template.backends.django.DjangoTemplates', 'DIRS': [], 'OPTIONS': {'context_processors': ['django.template.context_processors.debug', 'django.template.context_processors.request', 'django.contrib.auth.context_processors.auth', 'django.contrib.messages.context_processors.messages']}}] TEST_NON_SERIALIZED_APPS [] TEST_RUNNER 'django.test.runner.DiscoverRunner' THOUSAND_SEPARATOR ',' TIME_FORMAT 'P' TIME_INPUT_FORMATS ['%H:%M:%S', '%H:%M:%S.%f', '%H:%M'] TIME_ZONE 'UTC' USE_I18N True USE_L10N True USE_THOUSAND_SEPARATOR False USE_TZ True USE_X_FORWARDED_HOST False USE_X_FORWARDED_PORT False WSGI_APPLICATION 'dummy.wsgi.application' X_FRAME_OPTIONS 'DENY' YEAR_MONTH_FORMAT 'F Y' Thanks a lot for your help! Sincerely, Joalbert On Friday, February 4, 2022 at 1:54:44 PM UTC-5 [email protected] wrote: > Hmm that can't be right. > > Can you set a breakpoint on the line where the exception is raised: > SuspiciousFileOperation("Detected..... > > When you set a breakpoint there, inspect the value of dir_name. > > The ".parts" method breaks the file path up into a tuple, there shouldn't > be a ".." in the tuple. > > On Fri, Feb 4, 2022, 10:49 AM Joalbert Palacios <[email protected]> wrote: > >> Hi, >> >> dir_name in the exception is '/home/joalbert/Documents/Remesas >> App/RemesasServer/media/payments/images/filename.jpg' >> >> The setting for media is: >> Settings.py: >> MEDIA_ROOT = "./media/"#os.path.join(BASE_DIR, 'media') >> MEDIA_URL = '/media/' >> >> I try also with >> MEDIA_ROOT = os.path.join(BASE_DIR, 'media') >> where BASE_DIR = Path(__file__).resolve().parent.parent >> >> If you could tell me how could fix it, it would be nice. Since I do not >> have idea how to remove this exception. >> >> Sincerely, >> Joalbert >> On Friday, February 4, 2022 at 12:33:51 AM UTC-5 [email protected] >> wrote: >> >>> This is obviously some type of security feature to prevent someone from >>> climbing up a directory. You have ".." in your string for the file path >>> somewhere. >>> >>> What is the value of "dir_name" when the exception is raised? It should >>> be in the traceback somewhere. Should help narrow down where it's coming >>> from. Most likely a mistake you made in your settings file concating >>> strings related to where Django should upload files. >>> >>> On Thu, Feb 3, 2022, 2:12 PM Joalbert Palacios <[email protected]> >>> wrote: >>> >>>> Hi group, >>>> >>>> I have been updating my django version so as to cover the last security >>>> patch with django version 3.2 (current version 3.2.12). >>>> >>>> Unfortunately, after this update the following exception occurs during >>>> execution of testing: >>>> >>>> Detected path traversal attempt in '/home/joalbert/Documents/Remesas >>>> App/RemesasServer/media/payments/images/temp_qHaTViL.png' >>>> Bad Request: /webapp/payment >>>> >>>> I have read >>>> https://stackoverflow.com/questions/69745412/django-and-suspiciousfileoperationdetected-path-traversal-attempt >>>> >>>> and followed but not works in my case, maybe I misunderstood something, I >>>> would appreciate any help regarding how to fix those exception. >>>> >>>> I read django code and find the errors is in the following section: >>>> >>>> def get_available_name(self, name, max_length=None): >>>> >>>> """ >>>> >>>> Return a filename that's free on the target storage system and >>>> >>>> available for new content to be written to. >>>> >>>> """ >>>> >>>> name = str(name).replace('\\', '/') >>>> >>>> dir_name, file_name = os.path.split(name) >>>> >>>> if '..' in pathlib.PurePath(dir_name).parts: >>>> >>>> raise SuspiciousFileOperation("Detected path traversal attempt in '%s'" >>>> % dir_name) >>>> >>>> Here it is my code in the sections that code goes by to send response >>>> to client. >>>> >>>> *Model.py:* >>>> class Payment(models.Model): >>>> STATUS = ((0, _("Draft")), (1, _("Aproved")), (2 , _("Rejected")), (3, >>>> _("Released"))) >>>> order_number_id = models.OneToOneField(Exchange_Order, >>>> on_delete=models.CASCADE, related_name="order_payment") >>>> user_id =models.ForeignKey(User, verbose_name=_('user'), on_delete= >>>> models.CASCADE, related_name="payment_user_id") >>>> capture = models.FileField(verbose_name=_('image'), >>>> upload_to="payments/images", max_length=1024) >>>> payment_date = models.DateTimeField(verbose_name=_('date'), >>>> default=datetime.now().replace(tzinfo=timezone.utc)) >>>> status = models.PositiveSmallIntegerField(verbose_name=_('status'), >>>> default=0, choices=STATUS) >>>> reason = models.ForeignKey(Reasons,verbose_name=_('reason'), >>>> on_delete=models.CASCADE, related_name="payment_reason", >>>> null=True, blank=True) >>>> >>>> def __str__(self) -> str: >>>> return f"{self.order_number_id} {self.user_id.username} >>>> {self.payment_date}" >>>> class Meta: #new >>>> verbose_name = _("Payment from Client to 'Activo Digital'") >>>> verbose_name_plural = _("Payments from Client to 'Activo Digital'") >>>> >>>> *forms.py* >>>> class Payment_All_Form(forms.ModelForm): >>>> class Meta: >>>> model = Payment >>>> fields = "__all__" >>>> views.py (only post method is included for clarity) >>>> class PaymentSessionView(LoginRequiredMixin, CreateView): >>>> queryset = Payment.objects.all() >>>> form_class = Payment_Form >>>> http_method_names = ['get', 'post'] >>>> template_name="clienteServidor/webapp/payment.html" >>>> >>>> @method_decorator(User_Detail_Permission_Web) >>>> def post(self, request, *args, **kwargs): >>>> models = Exchange_Order.objects.filter(status=0, user_id=request.user) >>>> # En caso de que no haya ordenes abiertas >>>> if not models.exists(): >>>> context =self._add_context_data() >>>> context["existant"] ="No hay orden abierta" >>>> context["form"] = Payment_Form() >>>> return render(request,self.template_name, context) >>>> # Procesar pago para ordenes abiertas >>>> forms = [] >>>> data_list = [] >>>> order_ids = [] >>>> for model in models: >>>> my_data = self._complete_data(request, model.id) >>>> data_list.append(my_data) >>>> order_ids.append(f"Orden: {model.id}") >>>> forms.append(Payment_All_Form(my_data,request.FILES)) >>>> # Chequear que todas las formas sean validas >>>> are_valids = [] >>>> for form in forms: >>>> are_valids.append(form.is_valid()) >>>> # If any invalid >>>> if False in are_valids: >>>> for index, items in enumerate(are_valids): >>>> if not items: >>>> form = forms[index] >>>> context = self._add_context_data() >>>> context["form"] = form >>>> return render(request,self.template_name, context) >>>> for index, model in enumerate(models): >>>> if index == 0: >>>> forms[index].save() >>>> else: >>>> data_list[index]["order_number_id"]=model >>>> data_list[index]["user_id"]=request.user >>>> datum = {k:v for k,v in data_list[index].items() if >>>> k!="csrfmiddlewaretoken"} >>>> payment = Payment(**datum) >>>> payment.save() >>>> model.status=1 >>>> model.grouped_orders = order_ids >>>> model.save() >>>> my_message ="Orden Nro "+ str(model.id) + (" fue procesada >>>> exitosamente, les estaremos notificando" >>>> " por correo cuando el pago sea validado y procesado en el destino.") >>>> messages.add_message(request, messages.INFO, my_message) >>>> return HttpResponseRedirect(reverse_lazy("transaction_web")) >>>> >>>> Settings.py: >>>> MEDIA_ROOT = "./media/"#os.path.join(BASE_DIR, 'media') >>>> MEDIA_URL = '/media/' >>>> >>>> I hope sincerely that you could have any answer how to fix it. I really >>>> appreciate your help regarding this issue. >>>> >>>> Sincerely, >>>> Joalbert >>>> >>>> -- >>>> You received this message because you are subscribed to the Google >>>> Groups "Django users" group. >>>> To unsubscribe from this group and stop receiving emails from it, send >>>> an email to [email protected]. >>>> To view this discussion on the web visit >>>> https://groups.google.com/d/msgid/django-users/35a15616-92fc-41d4-97b3-8fb3061ec881n%40googlegroups.com >>>> >>>> <https://groups.google.com/d/msgid/django-users/35a15616-92fc-41d4-97b3-8fb3061ec881n%40googlegroups.com?utm_medium=email&utm_source=footer> >>>> . >>>> >>> -- >> You received this message because you are subscribed to the Google Groups >> "Django users" group. >> To unsubscribe from this group and stop receiving emails from it, send an >> email to [email protected]. >> > To view this discussion on the web visit >> https://groups.google.com/d/msgid/django-users/9de4405b-bff1-4b5f-a9ce-ec449d367d0en%40googlegroups.com >> >> <https://groups.google.com/d/msgid/django-users/9de4405b-bff1-4b5f-a9ce-ec449d367d0en%40googlegroups.com?utm_medium=email&utm_source=footer> >> . >> > -- You received this message because you are subscribed to the Google Groups "Django users" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. To view this discussion on the web visit https://groups.google.com/d/msgid/django-users/6382d561-87dd-4668-8864-73f3c61376ffn%40googlegroups.com.

