Как показать заголовок сообщения в динамической маршрутизации c url - PullRequest
1 голос
/ 12 июля 2020

В настоящее время я работаю над проектом веб-приложения в django, я хочу отображать заголовок сообщения в динамике c маршрутизация URL-адресов на странице сведений о публикации

Теперь мой URL-адрес похож на localhost / blog / detail / 1 '1 is post id' Я хочу добавить заголовок сообщения в URL-адрес выше с динамической c маршрутизацией URL-адресов, например localhost / blog / detail / name of the instance post / id

views.py

def blog_detail(request,id=None):
    instance=get_object_or_404(blogPost,id=id)
    args={"instance":instance}
    return render(request,'blog/blogDetail.html',args)

url.py

from django.conf.urls import url
from . import views

urlpatterns=[
url(r'^$',views.blog,name="blog"),
url(r'^details/(?P<id>[-\w]+)/$',views.blog_detail,name="details"),
]

models.py

from django.db import models
from django.urls import reverse

# Create your models here.

class blogPost(models.Model):
    postTitle=models.CharField(max_length=150)
    postContent=models.TextField(blank=False,default="Not found")
    category=models.CharField(max_length=50)
    author=models.CharField(max_length=100)
    updated=models.DateTimeField(auto_now=True,auto_now_add=False)
    timestamp=models.DateTimeField(auto_now=False,auto_now_add=True)

    def __unicode__(self):
        return self.postTitle

    def __str__(self):
        return self.postTitle

    def get_absolute_url(self):
        return reverse('details',kwargs={"id":self.id})

Ответы [ 2 ]

0 голосов
/ 12 июля 2020

Как упоминалось в ответе Бабака, вы, вероятно, захотите использовать поле слизняков. Если вы хотите, чтобы slugfield автоматически заполнялся на основе значения заголовка, вам необходимо переопределить метод save вашей модели (это потому, что значение slugfield должно быть установлено после того, как значение поля title уже известно). Кроме того, вы, вероятно, захотите изменить метод модели get_absolute_url. Вы можете, например, сделать это:

# models.py
from django.db import models
from django.urls import reverse
from django.utils.text import slugify #new


class BlogPost(models.Model): #changed
    postTitle=models.CharField(max_length=150)
    postContent=models.TextField(blank=False,default="Not found")
    category=models.CharField(max_length=50)
    author=models.CharField(max_length=100)
    updated=models.DateTimeField(auto_now=True,auto_now_add=False)
    timestamp=models.DateTimeField(auto_now=False,auto_now_add=True)
    slug = models.SlugField() # new

    def __unicode__(self):
        return self.postTitle

    def __str__(self):
        return self.postTitle

    def get_absolute_url(self):
        return reverse('details',kwargs={"id":self.id, "slug":self.slug}) #changed

    def save(self, *args, **kwargs): # new
        self.slug = slugify(self.postTitle)
        super().save(*args, **kwargs)

(обратите внимание, что я переименовал модель с blogPost в BlogPost в соответствии с Python соглашениями об именах для классов)

Вы Вам также нужно будет изменить файл urls.py, чтобы он работал с измененной моделью. Вот предложение (с использованием функции path вместо функции url, которую вы использовали в своем коде):

# urls.py
from django.urls import path #changed
from . import views

urlpatterns=[
    path('details/<slug:slug>/<int:id>/',views.blog_detail,name="details"), #changed
]

Если вы действительно используете этот подход, обратите внимание, что вам также необходимо изменить свое представление, так что он принимает аргумент slug (хотя представление на самом деле не должно делать что-либо с переменной slug):

# views.py
from django.shortcuts import render, get_object_or_404
from .models import BlogPost #changed

def blog_detail(request, slug, id=None): #changed
    instance=get_object_or_404(BlogPost,id=id)
    args={"instance":instance}
    return render(request,'blog/blogDetail.html',args)

Вот несколько тестов, которые я написал, чтобы проверить, что модель и view работают должным образом. Я включаю их сюда на случай, если они помогут прояснить поведение / что происходит.

# tests.py
from django.test import TestCase, Client
from django.urls import reverse

from .models import BlogPost

class ModelsTestCase(TestCase):
    def setUp(self):
        self.bp1 = BlogPost.objects.create(postTitle='First post',
                                           postContent='This is a post',
                                           category='Fun category',
                                           author='First author')

    def tearDown(self):
        pass

    def test_blogpost_slug(self):
        bp = BlogPost.objects.get(id=1)
        self.assertEqual(bp.slug, 'first-post')

    def test_blogpost_url(self):
        bp = BlogPost.objects.get(id=1)
        self.assertEqual(bp.get_absolute_url(), '/blog/details/first-post/1/')


class ViewsTestCase(TestCase):
    def setUp(self):
        self.bp1 = BlogPost.objects.create(postTitle='First post',
                                           postContent='This is a post',
                                           category='Fun category',
                                           author='First author')
        self.client = Client()

    def tearDown(self):
        pass

    def test_blog_detail_view_responds_with_status_code_200(self):
        firstpost_url = self.bp1.get_absolute_url()
        resp = self.client.get(firstpost_url)
        self.assertEqual(resp.status_code, 200)

Все три теста выполнены успешно.

Конечно, должно быть больше элегантное решение, когда дело доходит до шаблонов URL-адресов, которое не требует передачи в представление ненужного аргумента slug.

0 голосов
/ 12 июля 2020

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

если вы все равно хотите использовать это, вы должны использовать slugField, потому что в заголовке может быть пробел символ, который запрещен в веб-адресах.

для этого вам понадобится slugField в ваших моделях, который связан с вашим заголовком, и вам нужно изменить свой маршрут в urls.py примерно так:

url('details/<slug:title>',views.blog_detail,name="details")
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...