10

In settings.py I have:

BASE_DIR = Path(__file__).resolve().parent.parent

Then In some view:

from django.http import HttpResponse
from django.conf import settings


def test_view(request):
    return HttpResponse( settings.BASE_DIR.replace("src", "") )

This gives error: replace() takes 2 positional arguments but 3 were given

It confuses me, how that error appears? also if do:

return HttpResponse( settings.BASE_DIR )

this returns full path, something like: /home/full/path/to/project/src

also this works

 return HttpResponse( "/home/full/path/to/project/src".replace("src", "") )

Can you help me and tell what is wrong with this line:

return HttpResponse( settings.BASE_DIR.replace("src", "") )

?

Oto Shavadze
  • 40,603
  • 55
  • 152
  • 236

3 Answers3

18

Convert it to string:

str(settings.BASE_DIR).replace("src", "")
NKSM
  • 5,422
  • 4
  • 25
  • 38
  • 1
    BTW, error message seems bit confusing right? more relevant could be "replace() only works for string data types" or something like? just saying.. – Oto Shavadze Jan 28 '21 at 22:18
  • 2
    No, because `replace` actually **does work** for `Path` instances. It's just a different method. For exemple, calling `replace` on an `int` type will raise `AttributeError`. – Le Minaw Jan 28 '21 at 22:21
  • Yes, as @Le Minaw wrote, that is the intern method of `Path` instance. – NKSM Jan 28 '21 at 22:22
  • Now I see, so there is `str.replace()` and `Path.replace` also. Thank you – Oto Shavadze Jan 28 '21 at 22:28
  • 1
    @LeMinaw none of that explains the error message, which is cryptic at best. The error message is implying that three arguments were supplied when they were not. – Jeff Mar 19 '22 at 13:43
5

You're not calling the replace method of the str stype, but the one of the Path class from pathlib (because BASE_DIR is a Path instance).

It only takes two args (eg. my_path.replace(target)), therefore the exception.

Docs here about what is does (basically renaming a file or directory).

Cast your Path instance to a string.

Le Minaw
  • 835
  • 7
  • 17
2

From Django 3.1 BASE_DIR is by default set to new pathlib module Path object as documented

from source

BASE_DIR = Path(__file__).resolve().parent.parent

Coincidentally Path has also .replace() method but it does not have same use case as string replace

You might want to use instead parent accessor:

settings.BASE_DIR.parent
iklinac
  • 14,944
  • 4
  • 28
  • 30