From uploaded zipped shapefile to Geopandas DataFrame in Django Application

You can use fiona.io.ZipMemoryFile and gpd.GeoDataFrame.from_features.

Example:

import geopandas as gpd
import io
from fiona.io import ZipMemoryFile

# Just to create a BytesIO object for the demo,
# similar to your request.FILES['file'].file
zipshp = io.BytesIO(open('test.zip', 'rb').read())

with (ZipMemoryFile(zipshp)) as memfile:
    with memfile.open() as src:
        crs = src.crs
        gdf = gpd.GeoDataFrame.from_features(src, crs=crs)
        print(gdf.head())

Note, I originally didn't include the BytesCollection as the fiona developer stated in a comment on my previous answer that the class would likely be deprecated. However, if you use it, you shouldn't need ZipMemoryFile. This works for me:

import geopandas as gpd
import io
import fiona


zipshp = io.BytesIO(open('test.zip', 'rb').read())

with fiona.BytesCollection(zipshp.read()) as src:
    crs = src.crs
    gdf = gpd.GeoDataFrame.from_features(src, crs=crs)
    print(gdf.head())

@user2856's answer got me half way to a solution. I would not have known about fiona.io.ZipMemoryFile, and that led me to this answer. Combining the two solutions gave me:

with ZipMemoryFile(request.FILES['file'].file) as memfile:
    with fiona.BytesCollection(memfile._initial_bytes) as f:
        gdf = gpd.GeoDataFrame.from_features(f, crs='epsg:4326')
        print(gdf.head())

I now have my shapefile data in a GeoDataFrame.

For anyone who's curious, the reason I went with BytesCollection instead of memfile.open() is because I couldn't get memfile.open() to work. It would throw an error saying the .open() method was missing a 'path' positional argument.