我正在尝试使用django3.2和python3.9创建一个推特应用程序,我偶然发现了一个很难解决的问题。
当我试图保存一条tweet时,它的内容消失了。如果我直接使用pythonshell手动保存tweet的内容,那么该内容将正确保存。
但是,如果我从/home page或/create tweet/提交tweet,则会创建id,但内容为空。它也不会保存在db.sqlite3数据库中。
因此,表格似乎没有正确提交,但我不知道确切的原因是什么?
我的文件结构如下:
tweeterapp
┣ db.sqlite3
┣ manage.py
┣ templates
┣ components
┃ ┣ footer.html
┃ ┣ form.html
┃ ┗ navbar.html
┣ pages
┃ ┗ home.html
┣ tweets
┗ base.html
┣ tweeterapp
┣ settings.py
┣ urls.py
┣ wsgi.py
┗ __init__.py
┣ tweets
┣ migrations
┣ admin.py
┣ apps.py
┣ form.py
┣ models.py
┣ tests.py
┣ views.py
┗ __init__.py
form.hmtl:
<form method='POST'>{% csrf_token %}
{{ form.as_p }}
<button type='submit' class='btn btn-secondary'>Save</button>
</form>
home.html:
{% extends 'base.html' %}
{% block head_title %}
Test
{% endblock head_title %}
{% block content %}
<div class='row text-center'>
<div class='col'>
<h1> Welcome to the Tweeter version Max </h1>
</div>
</div>
<div class='row mb-3'>
<div class="col-md-4 mx-auto col-10">
<form class="form" id='tweet-create-form' method="POST" action="/create-tweet">
{% csrf_token %}
<input type="hidden" value="/" name="next" />
<textarea class="form-control" name="content" placeholder="Your tweet."></textarea>
<button type="submit" class="btn btn-primary">Tweet</button>
</form>
</div>
</div>
<div class='row' id='tweets'>
Loading...
</div>
<script>
function handleTweetCreateFormDidSumit(event) {
event.preventDefault()
const myForm = event.target
const myFormData = new FormData(myForm)
const url = myForm.getAttribute("action")
const method = myForm.getAttribute("method")
const xhr = new XMLHttpRequest()
xhr.open(method, url)
xhr.onload = function () {
const serverResponse = xhr.response
console.log(xhr.response)
const tweetsEl = document.getElementById("tweets")
loadTweets(tweetsEl)
}
xhr.send(myFormData)
}
const tweetCreateFormEl = document.getElementById("tweet-create-form")
tweetCreateFormEl.addEventListener("submit", handleTweetCreateFormDidSumit)
const tweetsEl = document.getElementById("tweets") // get an html element
function loadTweets(tweetsElement) {
const xhr = new XMLHttpRequest()
const method = 'GET'
const url = '/tweets'
const responseType = 'json'
xhr.responseType = responseType
xhr.open(method, url)
xhr.onload = function () {
// console.log(xhr.response)
const serverResponse = xhr.response
const listedItems = serverResponse.response // array
var finalTweetStr = ""
var i = 0;
for (i = 0; i < listedItems.length; i++) {
var tweetObj = listedItems[i]
var currentItem = formatTweetElement(tweetObj)
finalTweetStr += currentItem
}
tweetsElement.innerHTML = finalTweetStr
console.log(listedItems)
}
xhr.send()
}
loadTweets(tweetsEl)
function handleDidLike(tweet_id, currentCount) {
console.log(tweet_id, currentCount)
return
}
function LikeBtn(tweet){
return "<button class='btn btn-primary btn-sm' onclick=handleDidLike(" +
tweet.id + "," + tweet.likes + ")>" + tweet.likes + " Likes</button>"
}
function formatTweetElement(tweet){
var formattedTweet = "<div class='col-12 col-md-10 mx-auto border rounded py-3 mb-4 tweet' id='tweet-" + tweet.id
+ "'><p>" + tweet.content +
"</p><div class='btn-group'>" + LikeBtn(tweet) +
"</div></div>"
return formattedTweet
}
</script>
{% endblock content %}
form.py:
from django import forms
from .models import Tweet
MAX_TWEET_LENGTH = 240
class TweetForm(forms.ModelForm):
class Meta:
model = Tweet
fields = ['content']
def clean_content(self):
content = self.cleaned_data.get("content")
if len(content) > MAX_TWEET_LENGTH:
raise forms.ValidationError("This tweet is too long")
return content
models.py:
from django.db import models
class Tweet(models.Model):
# id = models.AutoField(primary_key=True)
content = models.TextField(blank=True,null=True)
image = models.FileField(upload_to='images/',blank=True,null=True)
views.py:
import random
from django.conf import settings
from django.shortcuts import render, redirect
from django.http import HttpRequest, HttpResponse, JsonResponse, Http404
from django.utils.http import is_safe_url
from .form import TweetForm
from .models import Tweet
ALLOWED_HOSTS = settings.ALLOWED_HOSTS
def home_view(request, *args,**kargs):
template_name = "pages/home.html"
context={}
status=200
return render(request,template_name,context,status=status)
def tweet_create_view(request,*args,**kwargs):
form = TweetForm(request.POST and None)
# print('post data is', request.POST)
next_url = request.POST.get("next") or None
print("next_url",next_url)
if form.is_valid():
obj = form.save(commit=False)
# do other form related logic
obj.save()
if next_url != None and is_safe_url(next_url, ALLOWED_HOSTS):
return redirect(next_url)
form = TweetForm()
return render(request, 'components/form.html', context={"form":form})
def tweet_list_view(request, *args,**kwargs):
"""
REST API VIEW
return Json Data
"""
qs = Tweet.objects.all()
tweets_list = [{"id":x.id,"content":x.content, "likes":random.randint(0,122)} for x in qs]
data = {
"isUser": False,
"response": tweets_list
}
return JsonResponse(data)
def tweet_detail_view(request, tweet_id, *args,**kargs):
"""
REST API VIEW
return Json Data
"""
data={
"id":tweet_id,
#"content":obj.content,
#"image_path":obj.image.url
}
status=200
try:
obj = Tweet.objects.get(id=tweet_id)
data['content']=obj.content
except:
data['message']="Not Found"
status=404
return JsonResponse(data,status=status) #json.dumps content_type='application/json'
暂无答案!
目前还没有任何答案,快来回答吧!