0

I am currently doing projct that includes Django and React.

Post model in django

models.py

class PublishedManager(models.Manager):
    def get_queryset(self):
        return super(PublishedManager,
                     self).get_queryset()\
            .filter(status='published')

class Post(models.Model):
    STATUS = (
        ('project', 'Project'),
        ('published', 'Published'),
    )
    title = models.CharField(max_length=250)
    slug = models.SlugField(
        max_length=250, unique_for_date='publish')
    author = models.ForeignKey(
        User, on_delete=models.CASCADE, related_name='messages')
    body = models.TextField()
    publish = models.DateTimeField(default=timezone.now)
    created = models.DateTimeField(auto_now_add=True)
    updated = models.DateTimeField(auto_now=True)
    status = models.CharField(max_length=15, choices=STATUS, default='projekt')

    objects = models.Manager()
    published = PublishedManager()

    class Meta:
        ordering = ('-publish',)

    def __str__(self):
        return self.title

    def get_absolute_url(self):
        return reverse("frontend.views.post_detail",
                       kwargs={'year': self.publish.year,
                               'month': self.publish.month,
                               'day': self.publish.day,
                               'slug': self.publish.slug})

views.py

def post_list(request):
    posts = Post.published.all()
    serializer = PostSerializer(posts, many=True)
    json_data = json.dumps(serializer.data)
    return render(request, 'frontend/index.html', {'posts': json_data})


def post_detail(request, year, month, day, post):
    post = get_object_or_404(Post, slug=post,
                             status='published',
                             publish__year=year,
                             publish__month=month,
                             publish__day=day)
    return render(request,
                  'frontend/index.html',
                  {'post': post})

I want to get the 'posts' from post_list and 'post' from post_detail to index.html which is start point for React.

index.html

<!DOCTYPE html>
<html lang="en">
  <head>
    [..]
    <script>
      const posts = {{ posts|safe }};
      const post = {{ post|safe }};
    </script>
    <link rel="stylesheet" href="{% static "css/style.css" %}" type="text/css">
  </head>
  <body>
      <div id="root"></div>
    <script src="{% static "frontend/main.js" %}"></script>

  </body>
</html>

The variables works perfectly fine when there's only one variable in script tag; what I mean is:

  • there's only one variable in script tag: const posts = {{ posts|safe }},
  • The code in react's component looks like {post.title} inside a paragraph,
  • I enter localhost:3000/posts/,
  • all posts from db are correctly displayed

The problem is, when I add another variable to the script tag (const post = {{ post|safe }}), it stops working, because the localhost:3000/posts/ no longer sees the post variable which is blank.

Also, I have hard time finding solution how to pass the get_absolute_url from model.py to work in a tag in react's components.

My final question is how to get this to work with multiple variables, i've already tried multiple times but nothing worked.

Raw output of '{{ posts|safe }}'

[
   {
      "id":2,
      "title":"wegew gqwr qw r",
      "slug":"wegew-gqwr-qw-r",
      "body":"wqg wqrg wqr qwwe gqwrg yh5rteh",
      "publish":"2021-11-07T17:46:57+03:00",
      "created":"2021-11-07T17:47:11.460183+03:00",
      "updated":"2021-11-07T17:47:11.460214+03:00",
      "status":"published",
      "author":1
   },
   {
      "id":1,
      "title":"dlaczego ja mam to pisac #2",
      "slug":"dlaczego-ja-mam-to-pisac-2",
      "body":"lorem lorem",
      "publish":"2021-11-07T13:18:38+03:00",
      "created":"2021-11-07T13:19:01.829642+03:00",
      "updated":"2021-11-07T17:46:04.150250+03:00",
      "status":"published",
      "author":1
   },
   {
      "id":3,
      "title":"post 3",
      "slug":"post-3",
      "body":"qwgr3qwgdrwdgf",
      "publish":"2021-10-06T19:09:22+03:00",
      "created":"2021-11-07T19:09:31.901192+03:00",
      "updated":"2021-11-07T19:10:02.729622+03:00",
      "status":"published",
      "author":1
   }
]

So it's an array, but the .map() function doesn't work.

After [posts].map()

Array(27) [ "[{\"id\": 2", " \"title\": \"wegew gqwr qw r\"", " \"slug\": \"wegew-gqwr-qw-r\"", " \"body\": \"wqg wqrg wqr qwwe gqwrg yh5rteh\"", " \"publish\": \"2021-11-07T17:46:57+03:00\"", " \"created\": \"2021-11-07T17:47:11.460183+03:00\"", " \"updated\": \"2021-11-07T17:47:11.460214+03:00\"", " \"status\": \"published\"", " \"author\": 1}", " {\"id\": 1", … ]
​
0: "[{\"id\": 2"
​
1: " \"title\": \"wegew gqwr qw r\""
​
2: " \"slug\": \"wegew-gqwr-qw-r\""
​
3: " \"body\": \"wqg wqrg wqr qwwe gqwrg yh5rteh\""
​
4: " \"publish\": \"2021-11-07T17:46:57+03:00\""
​
5: " \"created\": \"2021-11-07T17:47:11.460183+03:00\""
​
6: " \"updated\": \"2021-11-07T17:47:11.460214+03:00\""
​
7: " \"status\": \"published\""
​
8: " \"author\": 1}"
​
9: " {\"id\": 1"
​
10: " \"title\": \"dlaczego ja mam to pisac #2\""
​
11: " \"slug\": \"dlaczego-ja-mam-to-pisac-2\""
​
12: " \"body\": \"lorem lorem\""
​
13: " \"publish\": \"2021-11-07T13:18:38+03:00\""
​
14: " \"created\": \"2021-11-07T13:19:01.829642+03:00\""
​
15: " \"updated\": \"2021-11-07T17:46:04.150250+03:00\""
​
16: " \"status\": \"published\""
​
17: " \"author\": 1}"
​
18: " {\"id\": 3"
​
19: " \"title\": \"post 3\""
​
20: " \"slug\": \"post-3\""
​
21: " \"body\": \"qwgr3qwgdrwdgf\""
​
22: " \"publish\": \"2021-10-06T19:09:22+03:00\""
​
23: " \"created\": \"2021-11-07T19:09:31.901192+03:00\""
​
24: " \"updated\": \"2021-11-07T19:10:02.729622+03:00\""
​
25: " \"status\": \"published\""
​
26: " \"author\": 1}]"
​
length: 27

All right I figured out what needs to be done:

const posts = {{ posts|safe }}

posts.map((post, index) => 
    <p key={index}>{post.title}</p>
)}

to

const posts = '{{ posts|safe }}'

{JSON.parse(posts).map((post, index) => 
    <p key={index}>{post.title}</p>
)}
6
  • 1
    Can you try using quotes around the django variables: const post = "{{ post|safe }}"? See if this works. Commented Nov 8, 2021 at 16:47
  • Well, it kinda works but now I get an error TypeError: posts.map is not a function so posts aren't displayed and I don't know why, it returns the same array with objects in it. Commented Nov 8, 2021 at 17:01
  • What was the error you were getting before? Commented Nov 8, 2021 at 17:37
  • Uncaught SyntaxError: expected expression, got end of script and it was because I was rendering page like localhost:3000/posts/ to which data of all Posts were send, and I got the {{ posts|safe }} data, but on page localhost:3000/post/2021/11/07/lorem-lorem/ the posts data wasn't there, only for the single post. Commented Nov 8, 2021 at 17:49
  • 1
    I've answered a similar question about setting JS variables from Django: stackoverflow.com/a/43305140/1925257. If a context variable is a list or a dict and you want to use it in JS, you should first convert them to JSON data so that python specific keywords are translated to JS keywords (such as True to true and None to null, etc). Commented Nov 8, 2021 at 19:38

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.