【发布时间】:2021-05-24 20:05:13
【问题描述】:
我正在执行一项任务,以使用 fetch API 执行一些我们可以让 Python 在我们的视图中使用 JavaScript 执行的常规操作,例如添加记录或查询数据库。我遇到的一个问题是传递我们在 Django 中看到的普通属性,比如用户或用户名,当我使用 fetch API 从 sql 数据库中提取它时,它只是显示为文字用户 ID。使用我现在编写的视图、html 和 JavaScript,我将如何使用 JavaScript 中的 fetch 提取用户名,我通常可以在 Django 控制台中使用变量或使用 print 语句获取用户名,而不仅仅是查看用户 ID从数据库。我觉得我错过了一步,我只是没有看到它。
网址
app_name = "network"
urlpatterns = [
path("", views.index, name="index"),
path("login", views.login_view, name="login"),
path("logout", views.logout_view, name="logout"),
path("register", views.register, name="register"),
# API Routes
path("addpost", views.post, name="post"),
path("<str:navbar_item>", views.viewposts, name="viewposts"),
]
models.py
class User(AbstractUser):
pass
class Profile(models.Model):
user = models.OneToOneField(User, null=True, on_delete=models.CASCADE)
bio = models.TextField(null=True, blank=True)
# pics
website = models.CharField(max_length=225, null=True, blank=True)
follower = models.ManyToManyField(
User, blank=True, related_name="followed_user") # user following this profile
# profile user that follows this profile
following = models.ManyToManyField(
User, blank=True, related_name="following_user")
def __str__(self):
return f"{self.user}'s' profile id is {self.id}"
def following_users(self):
for username in self.following:
return username
def get_absolute_url(self):
return reverse("network:profile-detail", args=[str(self.id)])
class Post(models.Model):
created_by = models.ForeignKey(User, on_delete=models.CASCADE, related_name="post_user")
body = models.TextField(max_length=1000)
timestamp = models.DateTimeField(auto_now_add=True)
likes = models.ManyToManyField(User, blank=True, related_name="post_likes")
def __str__(self):
return f"{self.created_by} posted {self.body}"
def get_absolute_url(self):
return reverse("network:post-detail", args=[str(self.id)])
def total_likes(self):
return self.likes.count()
class Meta:
ordering = ["-timestamp"]
views.py
def index(request):
if request.user.is_authenticated:
return render(request, "network/index.html", {})
else:
return HttpResponseRedirect(reverse("network:login"))
@login_required
def post(request):
# Composing a new post must be done via POST
if request.method != "POST":
return JsonResponse({"error": "You must POST your request."}, status=404)
try:
data = json.loads(request.body)
body = data.get("body", "")
user = request.user
print(user)
post = Post(created_by=user, body=body)
# post = Post(created_by=Profile.objects.get(user=user), body=body)
post.save()
except AttributeError:
return JsonResponse({"error": "AttributeError thrown."}, status=500)
return JsonResponse({"message": "Post created."}, status=201)
@login_required
def viewposts(request, navbar_item):
if navbar_item == "viewposts":
posts = Post.objects.all()
posts = posts.order_by("-timestamp")
json_post = serialize("json", posts)
print(posts)
return HttpResponse(json_post, content_type="application/json")
else:
return JsonResponse({"error": "Invalid page."}, status=400)
index.html
{% extends "network/layout.html" %}
{% load static %}
{% block body %}
<div class="container p-5">
{% if error %}
{{ error }}
{% endif %}
<h1 class="display-4">All Posts</h1>
<div class="form-group border rounded p-4">
<h2 class="diplay-3">New Post</h2>
<form id="addpost" class="form-group pt-5">
{% csrf_token %}
<div class="form-group">
<textarea class="form-control" id="body" placeholder="Add post here..."></textarea>
</div>
<input type="submit" class="btn btn-primary"/>
</form>
</div>
<div id="all-posts" class="all-posts">
</div>
</div>
{% endblock %}
{% block script %}
<script src="{% static 'network/main.js' %}"></script>
{% endblock %}
JavaScript
// Post on index page # API Routes /addpost
const addPost = () => {
const addPostUrl = '/addpost';
const csrftoken = getCookie('csrftoken');
const body = document.querySelector('#body').value;
// body needs to be passed into an object before using the stringify method
const bodyObject = { body };
fetch(addPostUrl, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-CSRFToken': csrftoken,
},
body: JSON.stringify(bodyObject)
})
.then(response => response.json())
.then(result => {
console.log(result);
})
.catch(error => {
console.log(error);
});
return false;
};
// Load posts in index page # API Routes /navbar_item
function loadPosts(navItem, event) {
preventPageLoad(event);
const postUrl = `/${navItem}`;
// Send a GET request to the URL to retrieve all posts
fetch(postUrl)
.then(response => response.json())
.then(data => {
data.forEach(post => {
const { fields } = post;
const allPostsContainer = document.querySelector("#all-posts");
const element = document.createElement('div');
const postId = `#post-${fields.id}`;
element.style.textDecoration = 'none';
element.classList.add('HoverClass1');
element.setAttribute('id', `post-${fields.id}`);
element.classList.add('d-flex', 'flex-column' ,'justify-content-between', 'p-4', 'm-3', 'lead', 'border', 'rounded');
element.style.color = '#000000';
element.innerHTML =
// This is returning an id
`<div class="bd-highlight font-weight-bolder mr-5">${fields.created_by}</div>
<div class="bd-highlight">${fields.timestamp}</div>
<div class="flex-fill bd-highlight">${fields.body}</div>`;
console.log(fields);
allPostsContainer.append(element);
const linePost = document.querySelector(postId);
linePost.addEventListener('click', (event) => {
console.log(event);
});
});
})
.catch(error => {
console.log(error);
});
return false;
}
图像显示了我在 Django 中的管理控制台与浏览器控制台的对比,以及 JavaScript 中提取的内容。您会在管理控制台中看到我们可以查看用户名,但在浏览器控制台中,我得到的只是带有 fetch 的用户 ID。
【问题讨论】:
标签: javascript python django django-templates