Django вызывает noReverseMatch даже с правильным пространством имен - PullRequest
0 голосов
/ 17 октября 2019

У меня есть ниже urlpatterns в корне url.py:

urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^api/', include('api.urls'), name="api_app"),
]

, где api приложение содержит:

app_name="api_app"

urlpatterns = [

    url(r'^users/', views.UserList.as_view()),
    url(r'^users/(?P<user_type>[a-zA-Z_]+)$', views.UserList.as_view(), name="filter_type"),

    ...,
]

первый url отображает списокпользователей, а второй url принимает тип пользователя и фильтрует список пользователей с помощью user_type

Они оба работают нормально, когда я помещаю URL-адреса в адресную строку браузера. Однако, когда я пытаюсь сослаться на второй URL из шаблона django следующим образом:

<form action="{% url "api_app:filter_type" user_type %}" method="GET">
    <select name="user_type" class="userType">
        <option value="none">Select user type</option>
        <option value="A">A/option>
        <option value="B">B</option>
        <option value="C">C</option>
    </select>

            <input type="submit" value="Submit">

        </form>

Произошла ошибка ниже:

NoReverseMatch at /api/users/
Reverse for 'filter_type' with arguments '('',)' not found. 1 pattern(s) tried: ['api/users/(?P<user_type>[a-zA-Z_]+)$']

Почему это так? неправильно ли сконфигурированы пространства имен?

Проблема, очевидно, в том, что user_type нигде не определено, что я понимаю. Но с указанным выше тегом <Select>, как я могу определить user_type как выбранный параметр в html?

update

Это мое мнение, что я хочу передать данные user_typeдо:

class UserList(APIView):

    renderer_classes = [TemplateHTMLRenderer]

    def get(self, request, user_type=None):
        filters = {}
        if user_type:
            filters['user_type'] = user_type

        users = User.objects.filter(**filters)

        serializer = UserSerializer(users, many=True)

        return Response({"data": json.dumps(serializer.data)}, template_name="users.html")

Ответы [ 2 ]

0 голосов
/ 17 октября 2019

Вы определили свой URL-адрес следующим образом

url(r'^users/(?P<user_type>[a-zA-Z_]+)$', views.UserList.as_view(), name="filter_type")

Поэтому, когда вы выполняете обратный поиск URL-адреса, требуются параметры, соответствующие шаблону регулярных выражений [a-zA-Z_]+

Просмотр вашегокод, вы передаете user_type в URL

<form action="{% url "api_app:filter_type" user_type %}" method="GET"></form>

Тем не менее, он выдает эту ошибку

NoReverseMatch at /api/users/
Reverse for 'filter_type' with arguments '('',)' not found. 1 pattern(s) tried: ['api/users/(?P<user_type>[a-zA-Z_]+)$']

Это означает, что user_type является либо пустой строкой, либо неопределенной. user_type должна быть строкой, совпадающей с шаблоном [a-zA-Z_]+, чтобы вы могли выполнить обратное сопоставление с URL.

РЕДАКТИРОВАТЬ Вот как я бы это сделал, используяпредставление

<form action="view_user_type" method="POST">
    <select name="user_type" class="userType">
        <option selected="selected" disabled>Select user type</option>
        <option value="A">A/option>
        <option value="B">B</option>
        <option value="C">C</option>
    </select>
    <input type="submit" value="Select"
</form>


# forms.py

class UserTypeForm(forms.Form):
    USER_TYPE_CHOICES = (
        ('A', 'A'),
        ('B', 'B'),
        ('C', 'C'),
    )

    user_type = forms.ChoiceField(choices = USER_TYPE_CHOICES)


# views.py

from django.core.urlresolvers import reverse
from .forms import UserTypeForm

def view_user_type(request):
    if request.method == 'POST':
        form = UserTypeForm(request.POST)
        if form.is_valid():
            user_type = form.cleaned_data.get('value')
            return redirect(reverse('api_app:filter_type', args=(user_type,)))
0 голосов
/ 17 октября 2019

Проблема не в пространстве имен;это параметры. Вы передаете user_type, но оно либо пустое, либо (что более вероятно) не определено, где вы его используете, поэтому оно не соответствует ожидаемому параметру.

Редактировать Вызапутались. Вы помещаете /api/users в браузер и переходите на эту страницу. На этой странице у вас есть звонок на {% url "api_app:filter_type" user_type %}, который пытается сгенерировать ссылку;но user_type пусто, так что не может работать.

...