javascript—为什么我提交表单时对象的内容消失,而不是保存在数据库中?

tnkciper  于 2021-09-23  发布在  Java
关注(0)|答案(0)|浏览(164)

我正在尝试使用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'

暂无答案!

目前还没有任何答案,快来回答吧!

相关问题