CSRF 令牌在存在时丢失

问题描述 投票:0回答:1

我有一个表单,其中包含来自 forms.py 的不同表单对象。但是,当我尝试提交表单时,它说“csrf验证失败”

这是完整的模板(抱歉搞得一团糟,我稍后会在启动之前构建 js)

<!DOCTYPE html>
{% load static %}
{% load widget_tweaks %}
<html lang="en">
<head>

    <head>
    <title>{{app.name}}</title>

    <!-- Meta Tags -->
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
    <meta name="author" content="Webestica.com">
    <meta name="description" content="Bootstrap 5 based Social Media Network and Community Theme">

    <!-- Dark mode -->
    <script>
        const storedTheme = localStorage.getItem('theme')
 
        const getPreferredTheme = () => {
            if (storedTheme) {
                return storedTheme
            }
            return window.matchMedia('(prefers-color-scheme: light)').matches ? 'light' : 'light'
        }

        const setTheme = function (theme) {
            if (theme === 'auto' && window.matchMedia('(prefers-color-scheme: dark)').matches) {
                document.documentElement.setAttribute('data-bs-theme', 'dark')
            } else {
                document.documentElement.setAttribute('data-bs-theme', theme)
            }
        }

        setTheme(getPreferredTheme())

        window.addEventListener('DOMContentLoaded', () => {
            var el = document.querySelector('.theme-icon-active');
            if(el != 'undefined' && el != null) {
                const showActiveTheme = theme => {
                const activeThemeIcon = document.querySelector('.theme-icon-active use')
                const btnToActive = document.querySelector(`[data-bs-theme-value="${theme}"]`)
                const svgOfActiveBtn = btnToActive.querySelector('.mode-switch use').getAttribute('href')

                document.querySelectorAll('[data-bs-theme-value]').forEach(element => {
                    element.classList.remove('active')
                })

                btnToActive.classList.add('active')
                activeThemeIcon.setAttribute('href', svgOfActiveBtn)
            }

            window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', () => {
                if (storedTheme !== 'light' || storedTheme !== 'dark') {
                    setTheme(getPreferredTheme())
                }
            })

            showActiveTheme(getPreferredTheme())

            document.querySelectorAll('[data-bs-theme-value]')
                .forEach(toggle => {
                    toggle.addEventListener('click', () => {
                        const theme = toggle.getAttribute('data-bs-theme-value')
                        localStorage.setItem('theme', theme)
                        setTheme(theme)
                        showActiveTheme(theme)
                    })
                })

            }
        })
        
    </script>
    
    

    <!-- Favicon -->
    <link rel="shortcut icon" href="{% static 'media/logo.png' %}">

    <!-- Google Font -->
    <link rel="preconnect" href="https://fonts.googleapis.com">
    <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap">

    <!-- Plugins CSS -->
    <link rel="stylesheet" type="text/css" href="{% static 'main/css/all.min.css'%}">
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/font/bootstrap-icons.min.css">
    <link rel="stylesheet" type="text/css" href="{% static 'main/css/OverlayScrollbars.min.css' %}">
    <link rel="stylesheet" type="text/css" href="{% static 'main/css/tiny-slider.css' %}">
    <link rel="stylesheet" type="text/css" href="{% static 'main/css/choices.min.css'%}">
    <link rel="stylesheet" type="text/css" href="{% static 'main/css/glightbox.min.css'%}">
    <link rel="stylesheet" type="text/css" href="{% static 'main/css/dropzone.css'%}">
    <link rel="stylesheet" type="text/css" href="{% static 'main/css/flatpickr.css'%}">
    <link rel="stylesheet" type="text/css" href="{% static 'main/css/plyr.css'%}">
    <link rel="stylesheet" type="text/css" href="{% static 'main/css/zuck.min.css'%}">
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/all.min.css" integrity="sha512-DTOQO9RWCH3ppGqcWaEA1BIZOC6xxalwEsw9c2QQeAIftl+Vegovlnee1c9QX4TctnWMn13TZye+giMm8e2LwA==" crossorigin="anonymous" referrerpolicy="no-referrer" />
    <!-- TOM TOM -->
    <link
      rel="stylesheet"
      type="text/css"
      href="https://api.tomtom.com/maps-sdk-for-web/cdn/6.x/6.25.0/maps/maps.css"
    />
    <script src="https://api.tomtom.com/maps-sdk-for-web/cdn/6.x/6.25.0/maps/maps-web.min.js"></script>

    <!-- Theme CSS -->
    <link rel="stylesheet" type="text/css" href="{% static 'main/css/style.css'%}">
    
    
</head>

<body>

<!-- **************** MAIN CONTENT START **************** -->
<main>
  
  <!-- Container START -->
  <div class="container">
    <div class="row justify-content-center align-items-center vh-100 py-5">
      <!-- Main content START -->
      <div class="col-sm-10 col-md-8 col-lg-7 col-xl-6 col-xxl-5">
        <!-- Sign in START -->
        <div class="card card-body text-center p-4 p-sm-5">
          <!-- Title -->
          <h1 class="mb-2">Sign In</h1>
          <p class="mb-0">Already Registered? <a href="{% url 'login'%}"> Sign up</a></p>

          <!-- Form START -->
          <form class="mt-sm-4" method = 'POST' enctype="multipart/form-data">
            {% csrf_token %}
            {% render_field a_form.token type="hidden" hidden="true" readonly="true"%}
            <div id="card-1">
                <div class="mb-3 input-group-lg">
                    {% render_field u_form.first_name class="form-control" placeholder="First name" %}
                </div>
                <div class="mb-3 input-group-lg">
                    {% render_field u_form.last_name class="form-control" placeholder="Last name" %}
                </div>
                <div class="mb-3 input-group-lg">
                    {% render_field u_form.email class="form-control" placeholder="Email" %}
                </div>
                <div class="mb-3 input-group-lg">
                    {% render_field a_form.phone_number inputmode="tel" type="tel" class="form-control" placeholder="Phone" %}
                </div>
                <div class="mb-3 input-group-lg">
                    {% render_field u_form.username class="form-control" placeholder="Username" %}
                </div>
                <div class="mb-3 input-group-lg">
                    {% render_field a_form.DOB class="form-control" type="date" placeholder="Date Of Birth"%}
                </div>
                <div class="mb-3 input-group-lg">
                        <label style="float:left;">Profile Picture</label>
                        <div class="d-flex mt-1">
                        <div id="pswmeter-message" class="rounded"></div>
                        <!-- Password message notification -->
                        <div class="ms-auto">
                          <i class="bi bi-info-circle ps-1" data-bs-container="body" data-bs-toggle="popover" data-bs-placement="top" data-bs-content="We recommend you use a squared image showing your face. This will better help other know what you look like." data-bs-original-title="" title=""></i>
                        </div>
                      </div>
                    {% render_field a_form.picture class="form-control"%}
                </div>
                <div class="mb-3 input-group-lg">
                    <label style="float:left;">Your School:</label><br>
                    {% render_field a_form.school class="form-select" placeholder="School" %}
                </div>

                <style>
                    #id_gender{
                        border-top-left-radius: 0px;
                        border-bottom-left-radius: 0px;
                    }
                    #id_orientation{
                        border-top-right-radius: 0px;
                        border-bottom-right-radius: 0px;
                    }
                    #id_dating_type div, #id_target_ethnicity div{
                        float: left;
                    }
                    #id_dating_type, #id_target_ethnicity{
                        display: flex;
                        flex-direction: column;
                        align-items: flex-start;
                        justify-content: center;
                    }
                </style>
                <div class="mb-3 input-group-lg">
                        <label style="float:left;">I am a:</label><br>
                    <div class="d-flex">
                        {% render_field a_form.orientation class="form-select" placeholder="Gender" %}
                        {% render_field a_form.gender class="form-select" placeholder="Gender" %}
                    </div>

                </div>


                <div class="mb-3 input-group-lg">
                    <label style="float:left;">I am a:</label><br>
                    {% render_field a_form.ethnicity class="form-select" placeholder="Ethnicity/Race" %}
                </div>
                <div class="mb-3 input-group-lg">
                    <label style="float:left;">Status:</label><br>
                    {% render_field a_form.status class="form-select" placeholder="Status" %}
                </div>
                <div class="mb-3 input-group-lg">
                    <label style="float:left;">I want:</label><br>
                    {% render_field a_form.dating_type  placeholder="Dating Type" %}
                </div>
                <div class="mb-3 input-group-lg">
                    <label style="float:left;">I want:</label><br>
                    {% render_field a_form.target_ethnicity  placeholder="Dating Type" %}
                </div>
                <div class="mb-3 input-group-lg">
                        <label style="float:left;">Showoff Pictures</label>
                        <div class="d-flex mt-1">
                        <div id="pswmeter-message" class="rounded"></div>
                        <!-- Password message notification -->
                        <div class="ms-auto">
                          <i class="bi bi-info-circle ps-1" data-bs-container="body" data-bs-toggle="popover" data-bs-placement="top" data-bs-content="Choose up to 8 pictures. We will randomly feature this pictures in our dating platform. Allowing people to see these and figure out whether they think you are cute or not." data-bs-original-title="" title=""></i>
                        </div>
                      </div>
                    
                    <input type="file" name="images" id="image/*"  class="form-control" multiple onchange="limitFiles(this, 8)" style="margin-bottom:15px;">
                </div>


                <div class="mb-3 input-group-lg">
                        <div class="form-check form-switch" style="float:left;">
                                      {% render_field a_form.business_account class="form-check-input"  type="checkbox" role="switch"  %}
                                      <label class="form-check-label" for="id_business_account">Business Account</label>
                                    </div>
                        <div class="d-flex mt-1">
                        
                        <div class="ms-auto">
                          <i class="bi bi-info-circle ps-1" data-bs-container="body" data-bs-toggle="popover" data-bs-placement="top" data-bs-content="You will be able to access some features... like allowing users to pay entry fees to your paid events via {{app.name}}." data-bs-original-title="" title=""></i>
                        </div>
                      </div>
                        
                    <div id="business_info">
                        {% render_field a_form.paypal_username class="form-control" placeholder="Paypal Username (Optional)" %}

                    </div>
                    
                </div>

            </div>

            <br><br>
            <!-- New password -->
            <div class="mb-3 position-relative">
              <!-- Password -->
              <div class="input-group input-group-lg">
                {% render_field u_form.password1 class="form-control" type="password"  placeholder="Enter New Password"%}
                
              </div>
            </div>
            <!-- New password -->
            <div class="mb-3 position-relative">
              <!-- Password -->
              <div class="input-group input-group-lg">
                {% render_field u_form.password2 class="form-control fakepassword" type="password"id="psw-input" placeholder="Enter new password" %}
                <span class="input-group-text p-0">
                  <i class="fakepasswordicon bi bi-eye-slash cursor-pointer p-2 w-40px"></i>
                </span>
              </div>
            </div>
          
            <br>
            <div class="form-check " id="xyz" style="float:left;">
                            <input class="form-check-input" required type="checkbox" role="switch"  >
                          <label class="form-check-label" for="xyz">I agree to the <a href="" target="__blank">Terms Of Use</a> from {{app.name}}</label>
                        </div>
                        <br><br>
            


            
            

            <!-- Button -->
                
                <div style="transition:1s ease-in; width:100%;" class="d-grid"><button style="border-top-left-radius:0px; border-bottom-left-radius:0px;" id="submit_btn" class="btn btn-lg btn-primary-soft">Create Account <i class="bi bi-arrow-right"></i></button></div>
              <div>
                {% if messages|length > 0%}
                    <br>
                    {% for m in messages%}
                        <small class="text-danger">{{m}}</small><br>
                    {% endfor%}
                    
                {% endif %}
          </div>
            <!-- Copyright -->
            <p class="mb-0 mt-3">©{% now "Y"%} {{app.name}} By <a href="https://www.codecraftstudios.net/" target="__blank">CodeCraft Studios</a>.</a> </p>
            <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>

          </form>
          <!-- Form END -->
        </div>
        <!-- Sign in START -->
      </div>
    </div> <!-- Row END -->
  </div>
  <!-- Container END -->

</main>
<!-- **************** MAIN CONTENT END **************** -->
 

<!-- =======================
JS libraries, plugins and custom scripts -->
<script>

    function calculateAge(year, month, day) {
        // Get current date
        const currentDate = new Date();

        // Create a Date object using the provided year, month, and day
        const birthDate = new Date(year, month - 1, day); // Note: Month is 0-based

        // Calculate the age
        let age = currentDate.getFullYear() - birthDate.getFullYear();

        // Adjust age if the birthday hasn't occurred yet this year
        if (currentDate.getMonth() < birthDate.getMonth() ||
            (currentDate.getMonth() === birthDate.getMonth() && currentDate.getDate() < birthDate.getDate())) {
            age--;
        }

        return age;
    }

    document.addEventListener('DOMContentLoaded', function() {
        // Wait for the DOM to be fully loaded before accessing elements
        const dobInput = document.getElementById('id_DOB');
        const submitBtn = document.getElementById('submit_btn');
        if (dobInput) {
            dobInput.addEventListener('blur', function() {
                const dobValue = this.value;
                
                if (dobValue) {
                    const [year, month, day] = dobValue.split('-');
                    const userAge = calculateAge(parseInt(year), parseInt(month), parseInt(day));
                    console.log(`User's age is ${userAge}`);
                    
                    if(userAge < 18){
                        alert("You must be 18 years or older to use {{app.name}}.")
                        submitBtn.disabled = true;
                        dobInput.value = "";
                        dobInput.focus();
                    }
                    else{
                        submitBtn.disabled = false;
                    }
                }
            });

            // Set the minimum year for the date of birth input to today - 50 years
            const fiftyYearsAgo = new Date();
            fiftyYearsAgo.setFullYear(fiftyYearsAgo.getFullYear() - 50);
            const minYear = fiftyYearsAgo.getFullYear();
            dobInput.setAttribute('min', `${minYear}-01-01`);
        }
    });
</script>

<script>
        function getUserPlatform(){
            // Get user agent string
            var userAgent = navigator.userAgent;

            // Check if the user agent string contains keywords indicating Android, iOS, or Web
            if (/Android/i.test(userAgent)) {
                console.log('Device type: Android');
                return "android";
            } else if (/iPhone|iPad|iPod/i.test(userAgent)) {
                console.log('Device type: iOS');
                return "ios";
            } else {
                console.log('Device type: Web');
                return 'web';
            }
        }

setInterval(function(){
    let randomToken = generateRandomToken(32);
    $("#id_token").val(randomToken);
    $("#id_token").attr('type','hidden');
    $("#id_token").attr("readonly", true)
    $("#id_token").attr("hidden", true);


},300)
</script>
<script src="{% static '/main.js'%}"></script>
<!-- Bootstrap JS -->

<script src="{% static 'main/js/bootstrap.bundle.min.js' %}"></script>

<!-- Vendors -->
<script src="{% static 'main/js/tiny-slider.js'%}"></script>
<script src="{% static 'main/js/OverlayScrollbars.min.js'%}"></script>
<script src="{% static 'main/js/choices.min.js'%}"></script>
<script src="{% static 'main/js/glightbox.min.js'%}"></script>
<script src="{% static 'main/js/flatpickr.min.js'%}"></script>
<script src="{% static 'main/js/plyr.js'%}"></script>
<script src="{% static 'main/js/dropzone.min.js'%}"></script>
<script src="{% static 'main/js/zuck.min.js'%}"></script>
<script src="{% static 'main/js/zuck-stories.js'%}"></script>

<!-- Theme Functions -->

<script src="{% static 'main/js/functions.js'%}"></script>

<script src="https://cdn.jsdelivr.net/npm/@popperjs/[email protected]/dist/umd/popper.min.js" integrity="sha384-I7E8VVD/ismYTF4hNIPjVp/Zjvgyol6VFvRkX/vR+Vc4jQkC+hVqc2pM8ODewa9r" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.min.js" integrity="sha384-BBtl+eGJRgqQAUMxJ7pMwbEyER4l1g+O15P+16Ep7Q9Q+zqX6gSbd85u4mG4QzX+" crossorigin="anonymous"></script>

<script src="https://unpkg.com/[email protected]" integrity="sha384-D1Kt99CQMDuVetoL1lrYwg5t+9QdHe7NLX/SoJYkXDFfX37iInKRy5xLSi8nO7UC" crossorigin="anonymous"></script>
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery.inputmask/5.0.6/jquery.inputmask.min.js"></script>
<script>

$(document).ready(function() {
    $('textarea').on('keypress', function(e) {
        if (e.which === 13) {
            e.preventDefault();
        }
    });
    //Business account
    let b_a = document.getElementById("id_business_account");
        $("#business_info").hide();
    b_a.addEventListener('change', function(event) {
        // Check if the checkbox is checked
        if (event.target.checked) {
            $("#business_info").fadeIn("fast");
        } else {
            console.log('Checkbox is not checked');
            $("#business_info").fadeOut("fast");
            $("#id_paypal_username").val("");
        }
    })





    $('form').find('input, textarea, select').val('');
    // Apply input mask to the phone number field
    $('[name="phone_number"]').inputmask("(999) 999-9999", {
        placeholder: " ",
        clearIncomplete: true,
        removeMaskOnSubmit: true
    });

    $('[name="phone_number"]').on('keydown', function (e) {
        var key = e.which || e.keyCode;

        // Check if the pressed key is an arrow key (37: left, 38: up, 39: right, 40: down)
        if (key >= 37 && key <= 40) {
            e.preventDefault(); // Prevent default arrow key behavior
        }
    });
});


function limitFiles(fileInput, maxFiles) {
    // Get the selected files
    var files = fileInput.files;
    
    // If the number of selected files exceeds the limit, show an alert
    if (files.length > maxFiles) {
        alert('You can only upload a maximum of ' + maxFiles + ' files.');
        fileInput.value = ''; // Clear the file input to remove the selected files
    }
}

</script>


</script>


</body>
</html>
 

这是我的帐户的 models.py



# Auth

def upload_account_picture(i, n):
    return f'Users/{i.token}/profile-pictures/{n}'

class Account(models.Model):
    
    token = models.CharField(max_length=128, blank=True, null=True)
    

    user = models.OneToOneField(User, on_delete=models.CASCADE, null=True, blank=True)
    picture = models.ImageField(upload_to=upload_account_picture, blank=True)
    phone_number = models.CharField(max_length=16)
    bio = models.TextField(max_length=500)
    relationship_goals = models.TextField(max_length=300)
    gender = models.ForeignKey(Gender, on_delete=models.SET_NULL, null=True)
    orientation = models.ForeignKey(Orientation, on_delete=models.SET_NULL ,related_name="account_orientation", null=True)




    ethnicity = models.ForeignKey(Ethnicity, related_name="ethnicity",on_delete=models.SET_NULL, blank=True, null=True)
    target_ethnicity = models.ManyToManyField(Ethnicity)
    school = models.ForeignKey(School, related_name="School", on_delete=models.SET_NULL, blank=True, null=True)
    status = models.ForeignKey(Status, on_delete=models.SET_NULL, null=True)
    hobbies = models.ManyToManyField(Hobby, blank=True)
    dating_type = models.ManyToManyField(DatingType, blank=True)
    DOB = models.DateField(null=True)
    

    # stripe
    stripe_cus = models.CharField(max_length=128, blank=True, null=True)
    has_payment_method = models.BooleanField(default=False)
    stripe_account = models.CharField(max_length=128, blank=True, null=True)
    paypal_username = models.CharField(max_length=256, blank=True, null=True)

    # social
    followers = models.ManyToManyField(User, blank=True,  related_name="Followers")
    blocked = models.ManyToManyField(User, blank=True, related_name="Blocked")
    friends = models.ManyToManyField(User, blank=True, related_name="Friends")


    liked_people= models.ManyToManyField(User, blank=True, related_name="liked_people")
    disliked_people= models.ManyToManyField(User, blank=True, related_name='disliked_people')

    

    # Activity
    last_activity = models.DateTimeField(auto_now=True)
    is_active = models.BooleanField(default=False)

    business_account = models.BooleanField(default=False)

    def get_picture_urls(self):
        picture_urls = []
        account_pictures = self.accountpicture_set.all()  # Get all related AccountPicture objects
        for picture in account_pictures:
            picture_urls.append(picture.image.url)  # Append the URL of each image to the list
        return picture_urls
    

    def get_random_picture_url(self):
        account_pictures = self.accountpicture_set.all()  # Get all related AccountPicture objects
        if account_pictures:
            random_picture = random.choice(account_pictures)  # Select a random AccountPicture object
            return random_picture.image.url  # Return the URL of the randomly selected image
        else:
            return None  # Return None if there are no images associated with the account

    def get_followers(self, *args, **kwargs):
        return self.followers
    
    def get_friends(self, *args, **kwargs):
        return self.friends


    def __str__(self):
        return self.user.username


    def get_posts(self, *args, **kwargs):
        p = Post.objects.filter(user = self.user).distinct()
        print("P: ", p)
        return p

    def get_age(self):
        if self.DOB:
            today = datetime.date.today()
            age = today.year - self.DOB.year - ((today.month, today.day) < (self.DOB.month, self.DOB.day))
            return age
        return None

    class Meta: 
        ordering = ['user__username']

def account_pctures_upload(i, n):
    return f"Users/{i.account.token}/account-pictures/{n}"

class AccountPicture(models.Model):
    account = models.ForeignKey(Account, null=True, on_delete=models.CASCADE)
    image = models.ImageField(upload_to=account_pctures_upload)

    def __str__(self):
        return self.account.token


这是我的forms.py

from django.contrib.auth.forms import UserCreationForm
from django.contrib.auth.models import User
from django import forms
from .models import *


class PostForm(forms.ModelForm):
    class Meta:
        model = Post
        fields = "__all__"
        exclude =['likes', 'dislikes', 'blocked']

class AccountForm(forms.ModelForm):
    class Meta:
        model = Account
        fields = '__all__'
        exclude = ['stripe_cus', 'user', 'nationality', 'is_active']
        widgets = {
            'dating_type': forms.CheckboxSelectMultiple(),
            'hobbies': forms.CheckboxSelectMultiple(),
            'target_ethnicity': forms.CheckboxSelectMultiple()
        }



class ShowoffPictures(forms.ModelForm):
    class Meta:
        model=AccountPicture
        fields = ['image']

class User_Form(UserCreationForm):
    class Meta:

        model = User

        fields = ['first_name', 'last_name', 'username','email', 'password1', 'password2']

        labels = {
        'first_name':''
        }




    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        for i in self.fields:
            self.fields[i].widget.attrs.update({'required':''})


        self.fields['username'].widget.attrs.update({'autofocus': False})

views.py


def create_account(request):
    u_form = User_Form()
    a_form = AccountForm()
    a_pictures = ShowoffPictures()


    if request.method == "POST":
        print(request.POST)
        u_f  = User_Form(request.POST)
        a_f = AccountForm(request.POST, request.FILES)

        print(u_f, a_f)
        print(u_f.errors, a_f.errors)





    context = {
        'u_form': u_form,
        'a_form': a_form,
        'a_pics': a_pictures,
    }
    return render(request, f"{md}/create_account.html", context)




任何帮助将不胜感激。谢谢你

python django django-models django-forms django-middleware
1个回答
0
投票

在你的js中,

$('form').find('input, textarea, select').val('');

上面一行清空所有输入字段,包括 csrf_token。

排除 csrf_token 输入字段或包含必填字段。

排除方法::

$('form').find('input[name!='csrfmiddlewaretoken'], textarea, select').val('');
© www.soinside.com 2019 - 2024. All rights reserved.