Back2Basics
Back2Basics

Reputation: 7806

django cookiecutter media/ location for testing

Problem: I have an ImageField in a model. The TestCase isn’t able to find the default image file to perform a image resize on it (a @receiver(pre_save, sender=UserProfile) decorator thing)

class UserProfile(Model):
    user = ForeignKey(AUTH_USER_MODEL ...)
    ...
    photo = ImageField(
        verbose_name=_("Photo"),
        upload_to="media",
        null=True,
        blank=True,
        help_text=_("a photo will spark recognition from others."),
        default="default.png")

Overview: I’m running tests locally from pycharm to a docker container. This project is based on a django cookiecutter project.

I did a search for the target file in the presave hook and the file was found in these 2 directories ['/app/media/default.png', '/opt/project/media/default.png']

I am getting a FileNotFound error on '/app/<my_project_name>/media/default.png'

How do I get the media file to look in these directories?

@receiver(pre_save, sender=UserProfile)
def user_profile_face_photo_reduction(sender, instance, *args, **kwargs):
    """
    This creates the thumbnail photo for a concept
    """

    test_image_size(instance) # this is the function that gives problems.  it's below.
    im = generic_resize_image(size=face_dimensions, image=instance.photo)
    save_images_as_filename(
        filename=Path(instance.photo.path).with_suffix(".png"),
        image=im,
        instance=instance,
    ) 


def test_image_size(instance=None, size_limit=None):
    """
    size_limit is a namedtuple with a height and width that is too large to save.
    instance needs to have a photo attribute to work
    """
    if instance and instance.photo:
        print([x.absolute() for x in sorted(Path("/").rglob("default.png"))]) # this is where I got the actual location info
        assert instance.photo.size <= 10_000_000, ValueError("Image size is too big") # THE PROBLEM LINE IS THIS ONE.
        if (
            instance.photo.width > size_limit.width
            or instance.photo.height > size_limit.height
        ):
            raise ValueError(_("the picture dimensions are too big"))

Upvotes: 0

Views: 355

Answers (2)

Back2Basics
Back2Basics

Reputation: 7806

I started off creating a "media" directory in the app_root folder (/Users//<project_name>/). That was a dumb move. There is already a media folder in the (/Users//<project_name>/<project_name>/media) folder which I didn't see. I tried to force it using tricks like the docker mounting trick and changing my code, it was a waste of time.

I upvoted @heyylateef's answer for the override_settings because that is a neat decorator.

Upvotes: 1

heyylateef
heyylateef

Reputation: 76

  1. Did you mount the host machine's media volume to the dockerfile? You may need to show us the dockerfile so we can have a better understanding of your configuration.

  2. If running tests using a folder directly on the host machine isn't a hard requirement, you can create another folder in your Django project root folder (i.e. "testmedia"). In your tests.py file, you can override your media root settings for your tests to use the "testmedia" folder. Place your test image file in the folder. Here is an example of overriding media root settings:

    TEST_DIR = os.path.join(settings.BASE_DIR, 'testmedia/') #Defines test media root
    
    @override_settings(MEDIA_ROOT=(TEST_DIR))
    def test_create_blogpost(self):
     print("\nTesting blog post creation...")
    
     testUser = User.objects.create_user(username='testUser', password='12345') #Creates test user
     self.client.login(username='testuser', password='12345') #Logs in testUser
    
     PNGtestpic = SimpleUploadedFile(name="pngtest.png", content=open(settings.MEDIA_ROOT + "pngtest.png", 'rb').read(), content_type='image/png') #Uploads test picture to media root
     Blogpost.objects.create(title="How to run tests", cover_image= PNGtestpic, author=testUser)
    

Upvotes: 1

Related Questions