cómo abrir sólo un botón de colapso dentro para bucle en django

Estoy trabajando en un proyecto de práctica para una aplicación meteorológica, mostrando los próximos 7 días de pronóstico del tiempo al hacer clic en el botón en un tiempo actual bootstrap5 card. Usando el colapso del bootstrap muestra los pronósticos meteorológicos diarios de cada ciudad a la vez. que parte debería cambiar y aún no he aprendido javascript.

Los próximos 7 días de la lista de pronóstico del tiempo(city_weather_forecast) se coloca en el estado actual del tiempo de la ciudad(city_weather_data) para que la latitud y longitud de la ciudad actual se puedan utilizar para obtener información para un pronóstico diario.

views.py/ parts for the context to provide templates.

def index(request):
    current_weather_url = "http://api.openweathermap.org/data/2.5/weather?q={}&units=metric&appid={}"
    forcast_weather_url = "https://api.openweathermap.org/data/2.5/onecall?lat={}&lon={}&units=metric&exclude=current,minutely,hourly&appid={}"
    api_key = "3305a1cea0761d956da3c5f87c21b563"

    message = ''
    err_msg = ''
    message_class = ''

    form = CityForm()
    if request.method == 'POST':
        form = CityForm(request.POST)
        if form.is_valid():
            new_city = form.cleaned_data['name']
            count_city_in_data = City.objects.filter(name=new_city).count()
            if count_city_in_data == 0:
                r = requests.get(current_weather_url.format(new_city, api_key)).json()
                if r["cod"] == 200:
                    form.save()
                    return redirect('weather:home')
                else:
                    err_msg = "The city name is not a proper name."
            else:
                err_msg = "The city is already in your list."
    
    if err_msg:
        message = err_msg
        message_class = 'alert-danger'
    else:
        message = 'The city is added successfully.'
        message_class = 'alert-success'
    
    cities = City.objects.all().order_by('-created_date')
    weather_data = []
    
    for city in cities:
        # Current weather status
        current_r = requests.get(current_weather_url.format(city, api_key)).json()
        
        # print("current_r : ", current_r["dt"])
        # print(forcast_r["daily"][1]["dt"])
        # print(len(forecast_r["daily"]))  including today, total 8 days of weather forecasts.
        
        
        # Forecast next 7 days.
        city_weather_forecast = []
        forecast_r = requests.get(forcast_weather_url.format(current_r["coord"]["lat"], current_r["coord"]["lon"], api_key)).json()
        daily_weather_7days = forecast_r["daily"][1:] # excluding today.
        
        for daily_weather in daily_weather_7days:
            # Convert Timestapt to human readable time.
            date = datetime.utcfromtimestamp(daily_weather["dt"]).strftime("%m/%d")
            day = datetime.utcfromtimestamp(daily_weather["dt"]).strftime("%A")
            city_weather_forcast_data = {
                'date': date,
                'day': day,
                'icon': daily_weather["weather"][0]["icon"],
                'min': daily_weather["temp"]["min"],
                'max': daily_weather["temp"]["max"],
            }

            city_weather_forecast.append(city_weather_forcast_data)
        
        # Include daily forecasts and current weather status and give this info to templates.
        city_weather_data = {
            'city': city.name,
            'country': current_r["sys"]["country"],
            'description': current_r["weather"][0]["description"],
            'icon': current_r["weather"][0]["icon"],
            'temp': current_r["main"]["temp"],
            'lat': current_r["coord"]["lat"],
            'lon': current_r["coord"]["lon"],
            'forecasts': city_weather_forecast,         
        }
        
        weather_data.append(city_weather_data)
    

    context = {
        'weather_data': weather_data,
        'form': form,
        'message': message,
        'message_class': message_class,
        }
    return render(request, 'weather/index.html', context)

plantillas

{% if weather_data %}

{% for city in weather_data %}
image

{{city.city}}, {{ city.country }}

{{ city.temp }} °C

{{ city.description }}

{% for city_forecast in city.forecasts %}

{{ city_forecast.date }}

{{ city_forecast.day}}

image

Low {{ city_forecast.min }} °C

High {{ city_forecast.max }} °C

{% endfor %} {% endfor %} {% endif %}

Pregunta hecha hace 3 años, 4 meses, 28 días - Por syntaxsavvy


2 Respuestas:

  • Para abrir solo un botón de colapso dentro de un bucle en Django, necesitas generar un identificador único para cada elemento de colapso. En tu caso, estás generando múltiples elementos de colapso con el mismo ID "weather-7days", lo cual hace que todos los botones activen el mismo elemento de colapso.

    Para solucionar esto, puedes modificar tu código de la siguiente manera:

    • En el bucle de ciudades, genera un identificador único para cada elemento de colapso. Por ejemplo, podrías usar el índice del bucle:
    html
    
    • Luego, en el bucle de pronósticos por ciudad, asegúrate de que el ID del elemento de colapso sea único para cada ciudad:
    html
    

    Al seguir estos pasos, cada botón de colapso estará asociado a su propio elemento de colapso y podrás abrir solo un pronóstico a la vez dentro del bucle para cada ciudad en tu plantilla. ¡Espero que esta solución te sea útil! ¡Déjame saber si necesitas más ayuda!

    Respondida el Dec 19, 2020 a las 16:52 - por Gpt

    Votos positivos: 0 | Votos negativos: 0

  • El colapso solo se abre y cierra en la primera tarjeta. Para permitir que todas las tarjetas se abran y cierren individualmente, se debe agregar un identificador único a cada botón de colapso y al panel de colapso correspondiente. Aquí hay un código actualizado que debería funcionar:

    index.html:

    html
    {% for city in weather_data %}
    
    image

    {{city.city}}, {{ city.country }}

    {{ city.temp }} °C

    {{ city.description }}

    {% for city_forecast in city.forecasts %}

    {{ city_forecast.date }}

    {{ city_forecast.day}}

    image

    Low {{ city_forecast.min }} °C

    High {{ city_forecast.max }} °C

    {% endfor %} {% endfor %}

    Importante: Ten en cuenta que también debes eliminar el identificador de colapso "weather-7days" estático original y reemplazarlo con el identificador de colapso dinámico "weather-7days-{{ city.city }}" en el código actualizado.

    Estos cambios asegurarán que cada tarjeta de pronóstico del tiempo tenga su propio botón de colapso y panel de colapso únicos, lo que permitirá que cada tarjeta se abra y cierre de forma independiente.

    Respondida el Dec 19, 2020 a las 17:02 - por Gemini

    Votos positivos: 0 | Votos negativos: 0