Problema de representación de CSS al pasar valores en solicitudes "obtener" con Python + Jinja2 + GAE

StackOverflow https://stackoverflow.com//questions/10709361

Pregunta

Esta es la primera vez que publico en Stack Overflow.Estoy intentando crear un juego relativamente simple usando Python, Jinja2 y Google App Engine.Por el momento, acabo de crear algunas funciones CRUD simples para crear, editar, enumerar y destruir juegos.Y, en su mayor parte, parece funcionar.Pero parece que mi hoja de estilo CSS no se aplica cada vez que paso un valor para recuperar un juego específico.Sin embargo, parece funcionar bien siempre que no paso ningún valor.Por ejemplo, si llamo a funciones como "create_game" o "all_games", que no toman ningún parámetro, sus respectivas plantillas se representan correctamente con los estilos CSS relevantes.Pero, si llamo a una función como "edit_game/12345567", la hoja de estilos CSS no se aplica en absoluto, aunque las etiquetas html y el contenido generado por Python parecen funcionar.

No estoy muy seguro de dónde reside el problema.¿Podría esto tener algo que ver con la forma en que se representan las plantillas?¿O es algún tipo de problema de enrutamiento/mapeo?

Aquí está mi main.py:

    import webapp2
    from controllers.authController import *
    from controllers.baseController import *
    from controllers.gameController import *

    app = webapp2.WSGIApplication([('/', MainPage),                     
            ('/create_game',CreateGame),
            ('/player_games/([\d]+)',PlayerGames),
            ('/all_games',AllGames),
            ('/edit_game/([\d]+)',EditGame),
            ('/delete_game/([\d]+)',DeleteGame),
                    ],
                    debug=True)

y mi baseController.py:

from controllers.authController import LoginSession
import webapp2
import cgi
import datetime
import urllib
import jinja2
import os
import wsgiref.handlers
from google.appengine.api import users

TEMPLATE_DIR = os.path.join(os.path.dirname(__file__), '../views/templates')
jinja_environment = \
        jinja2.Environment(loader=jinja2.FileSystemLoader(TEMPLATE_DIR))

class BaseHandler(LoginSession):
    @webapp2.cached_property
    def jinja2(self):
        return jinja2.get_jinja2(app=self.app)

    def render_template(
            self,
            filename,
            temp_values,
            **template_args):
            template = jinja_environment.get_template(filename)
            self.response.out.write(template.render(temp_values))

    def authvals(self): 
            current_player = LoginSession.current_player(self)
            url = LoginSession.url(self)
            url_linktext = LoginSession.linktext(self)
            auth_vals = {
                    'url': url,
                    'url_linktext': url_linktext,
                    'c_player': current_player,
            }
            return auth_vals

class MainPage(BaseHandler):    

    def get(self):
            gurl = self.request.get('/create_game')
            gurl_linktext = 'Create a New Game!'
            mp_vals = {
                    'game_url': gurl,
                    'game_url_linktext': gurl_linktext,
            }
            authvals = self.authvals()
            vals = dict(mp_vals.items() + authvals.items())
            self.render_template('index.html', vals)

A continuación se muestran dos clases de gameController.py.Mientras que "AllGames" parece representar todo correctamente, incluido el estilo CSS correcto, "PlayerGames" parece representar el contenido html y generado por Python correcto, pero no parece hacer uso de ningún CSS.Esperaría que el CSS se herede junto con "base.html", ya que ahí es donde se aplican los estilos CSS.Pero, de alguna manera, esto no está sucediendo.

from models.gameModel import *
from authController import *
from baseController import * 
import baseController
from google.appengine.ext import db
from google.appengine.ext.db import Key

class AllGames(BaseHandler):

    #this returns all games 
    def get(self):
        games = GameModel.all()
        ag_vals = {
            'games': games
        }
        authvals = self.authvals()
        vals = dict(ag_vals.items() + authvals.items())

        self.render_template('all_games.html',vals)

class PlayerGames(BaseHandler):

    #This returns a given player's games
    def get(self,player_id):
        player = users.User(_user_id = 'player_id')

        g = GameModel.all()
        games = g.filter('game_created_by =', player)         
        pg_vals = {
        'games': games
        }
        authvals = self.authvals()
        vals = dict(pg_vals.items() + authvals.items())

        self.render_template('player_games.html',vals)  

Aquí está base.html:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
<html lang="en">
<html xmlns="http://www.w3.org/1999/xhtml">

<html>
<head>
{% block head %}
    <link type="text/css" rel="stylesheet" href="views/static/css/main.css" />
    <link type="text/css" rel="stylesheet" href="views/static/css/reset.css" />
    <title>O2O: {% block title %}{% endblock %}</title>
{% endblock %}
</head>
<body>
<div class="login">
    {% block login %}
        <table>
            <tr>
                {% if c_player %}
                    <td>You are logged in as: {{ c_player }} </td>
                {% else %}
                    <td>You are not logged in.</td>
                {% endif %}

                <td><a href="{{ url }}">{{ url_linktext }}</a></td> 
            </tr>
        </table>
    {% endblock login %}
</div>
<div class="navbar">
    {% block navbar %}
    <table>
        <col class="navbar" />
        <colgroup class="controls"> 
            <col /> <col /> <col /> <col />
        </colgroup> 
        <tr>
            <th>
                <form action="/create_game" method="post"> 
                    <div><input type="submit" value = "Create a new Game!"></div>
                </form>
            </th>
            <th>
                <form action="/player_games/{{ c_player.user_id() }}" method="get">
                    <!--div><input type="hidden" value = {{ c_player.user_id() }} ></div-->
                    <div><input type="submit" value = "My Games" ></div>
                </form>
            </th>
            <!--th>
                <a href ="player_games/{{ c_player.user_id() }}">My Games</a>
            </th-->
            <th>
                <form action="/all_games" method="get">
                    <div><input type="submit" value = "All Games" ></div>
                </form>
            </th>

            <th>
                Stats?
            </th>
            <th>
                Current Games?
            </th>
        </tr>   
    </table>
    {% endblock navbar %}
</div>
<div class="content">{% block content %}{% endblock %}</div>
<div class="footer">
    {% block footer %}
    &copy; Copyright 2012</a>.
    {% endblock %}
</div>
</body>
</html>

Aquí está all_games.html, que parece estar representado correctamente:

{% extends "base.html" %}
{% block title %} All Games {% endblock %}
{% block content %}     
    <h2>All Games</h2>

    <h4>These are all of the games:</h4>
        <table>
            <tr>
                <th>Time Created:                   </th>
                <th> ----------                     </th>
                <th>Game ID:                        </th>
                <th>Creator:                        </th>
                <th>Edit?                           </th>
                <th>Edit via button?                </th>
                <th>Delete?                         </th>
            </tr>       
            {% for game in games %}
            <tr>                
                <td> {{ game.game_created_at }}     </td>
                <td> ----------                     </td>   
                <td> {{ game.key().id() }}          </td>
                <td> {{ game.game_created_by }}     </td>
                <td>
                    <a href ="edit_game/{{ game.key().id() }}"> edit </a>
                </td>
                <td>    
                <!--button to view the game --> 
                    <form action="/edit_game/{{ game.key().id() }}" method="get">
                        <!--div><input type="hidden" name ="game_id" value={{ game.key().id() }}></div-->
                        <div><input type="submit" value = "Edit Game!" ></div>
                    </form> 
                </td>
                <td>        
                <!-- button to destroy the game -->
                    <form action="/delete_game/{{ game.key().id() }}" method="get">
                        <!--div><input type="hidden" name ="this_game" value={{ game.key().id() }}></div-->
                        <div><input type="submit" value = "Delete This Game?" ></div>
                    </form>
                </td>                           
            </p>
            </tr>                               
        {% endfor %}
        </table>        
{% endblock %}

y aquí está player_games.html, que es casi idéntico a all_games.html.Sin embargo, esto parece renderizarse sin CSS, aunque el html y el contenido aparentemente se muestran correctamente:

{% extends "base.html" %}
{% block title %} PLayer's Games {% endblock %}
{% block content %}
    <h2>{{ c_player }}'s Games</h2>

    <h4>These are all of the games:</h4>
    <div id="gamelist">
        <table>
            <tr>
                <th>Time Created:                   </th>
                <th> ----------                     </th>
                <th>Game ID:                        </th>
                <th>Creator:                        </th>
                <th>Edit?</th>
                <th>Delete?</th>
            </tr>       
            {% for game in games %}
            <tr>                
                <td> {{ game.game_created_at }}     </td>
                <td> ----------                     </td>   
                <td> {{ game.key().id() }}  </td>
                <td> {{ game.game_created_by }}     </td>
                <td>    
                <!--button to edit the game --> 
                    <form action="/edit_game/{{ game.key().id() }}" method="get">
                        <!--div><input type="hidden" name ="game_id" value={{ game.key().id() }}></div-->
                        <div><input type="submit" value = "Edit Game!" ></div>
                    </form> 
                </td>
                <td>        
                <!-- button to destroy the game -->
                    <form action="/delete_game/{{ game.key().id() }}" method="get">

                        <div><input type="submit" value = "Delete This Game?" ></div>
                    </form>
                </td>                           
            </p>
            </tr>                               
        {% endfor %}
        </table>
    </div>
{% endblock %}

Aquí está el archivo main.css, que probablemente no sea el problema, ya que se muestra correctamente en algunas de las páginas:

.login {
    background-color: black;
    color: #DDDDDD;
}

.navbar {
    background-color: black;
    color: #DDDDDD;
}

.content {
    background-color: white;
}

.footer {
    background-color: #DDDDDD;
}

Aunque dudo que esto sea realmente relevante para el problema, aquí también está authController.py:

import webapp2
import main
from google.appengine.api import users

class LoginSession(webapp2.RequestHandler):
    def current_player(arg):
        return users.get_current_user() 

    def linktext(arg):
        if users.get_current_user():
            return 'logout'
        else:
            return 'Login'

    def url(arg):
        if users.get_current_user():
            return users.create_logout_url(arg.request.uri)
        else:
            return users.create_login_url(arg.request.url)

He basado parte de mi código en este sencillo ejemplo de aplicación para tomar notas: https://github.com/fRuiApps/cpfthw/tree/master/webapp2 porque encontré que tiene una estructura MVC clara y agradable.Obviamente mi código es un poco más extenso, pero parte del código sobre cómo se deben representar las plantillas se basa más o menos en el ejemplo.Sin embargo, el ejemplo no sufre el problema de desaparición del estilo CSS que parece estar teniendo.Es decir.cuando paso solicitudes para editar una nota específica, el ejemplo parece representar el CSS correctamente.

Llevo un par de horas intentando solucionar este problema y, a pesar de todos mis esfuerzos, parece que no consigo llegar a ninguna parte.Como normalmente puedo encontrar información realmente útil en StackOverflow, pensé que este sería probablemente el mejor lugar para publicar el problema.¡Cualquier ayuda sería muy apreciada!¡Gracias!

¿Fue útil?

Solución

Estás cargando el CSS con una ruta relativa.Cuando el HTML es una página de 'nivel superior' (/create_game), entonces la ruta CSS es relativa a la raíz y todo está bien.Cuando estás abajo un nivel (/edit_game/1234), el CSS intenta cargar desde /edit_game/views.Cambie los enlaces hrefs en su HTML para comenzar/vistas y podría funcionar.(Si marca las herramientas de desarrollo en el navegador de su elección, debería ver 404 para el CSS y podrá ver desde dónde intenta cargarlos el navegador).

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top