Как мне переключить логическое поле

#python #django

#python #django

Вопрос:

Я работаю над проектом, в котором у пользователя есть свой собственный профиль, я хочу создать логическое поле в модели, чтобы пользователь мог установить конфиденциальность профиля, частную или общедоступную. Я добавил логическое поле в modal (is_private). Также у меня есть переключатель для шаблона, но я не знаю, как использовать его с Django. Я хочу, чтобы при нажатии пользователем кнопки переключить логическое поле на значение true (private), при повторном нажатии пользователем кнопки переключить логическое поле на значение false (public). Возможно, также необходим Jquery.

введите описание изображения здесь

Модель:

 class Profile(models.Model):
    user = models.OneToOneField(settings.AUTH_USER_MODEL,on_delete=models.CASCADE,blank=True,null=True) 
    is_private = models.BooleanField(default=False)
  

Число просмотров:

 def profile_edit_view(request):
    p = Profile.objects.filter(user=request.user).order_by('-id')
    context = {'p':p}
    return render(request, 'profile_edit.html', context)
  

url-адреса:

 path('account/edit/', profile_edit_view, name ='profile-edit'),
  

Шаблон редактирования профиля:

 <form method="POST" name="is_private">
 {% csrf_token %}
<div class="custom-control custom-switch">
 <input type="checkbox" class="custom-control-input" id="customSwitches" name="is_private">
 <label class="custom-control-label" for="customSwitches">Private Account</label>
 </div>
 </form>
<p class="text-muted font-weight-normal font-small">
  When your account is private, only people you approve can see your photos and videows on Pixmate. Your existing followers won't be affected.
</p>
  

Комментарии:

1. атрибут name отсутствует для поля ввода name="is_private" Если вы работаете с ModalForm, то должно быть указано соответствующее имя, указанное в классе Form

2. @AchuthVarghese… Спасибо за это понимание. Можете ли вы помочь мне с views.py ? Я не нашел никакого руководства о том, как переключать логическое поле в Django

3. Зачем нужен order_by в вашей функции views? Был бы только один профиль, соответствующий пользовательскому праву.

Ответ №1:

  1. В файле шаблона измените входной тег, как показано
 <!-- Mark the checkbox as checked or not by is_private -->
<input type="checkbox" class="custom-control-input" id="customSwitches" {% if p.is_private %}checked{% endif %}>
  

В тот же файл шаблона добавьте этот скрипт

 <script type="text/javascript">
    $(document).ready(function() {
        // send request to change the is_private state on customSwitches toggle
        $("#customSwitches").on("change", function() {
            $.ajax({
                url: "{% url 'change_privacy' %}",
                data: {
                    csrfmiddlewaretoken: "{{ csrf_token }}",
                    is_private: this.checked // true if checked else false
                },
                type: "POST",
                dataType : "json",
            })
            // $.ajax().done(), $.ajax().fail(), $ajax().always() are upto you. Add/change accordingly
            .done(function(data) {
                console.log(data);
                // show some message according to the response. 
                // For eg. A message box showing that the status has been changed
            })
            .always(function() {
                console.log('[Done]');
            })
        })
    });
</script>
  
  1. Добавьте новый путь в свой файл urls приложения, который привязывается к представлению. Скажите: функция, названная change_privacy() в ваших представлениях
 path('changeprivacy', change_privacy, name="change_privacy"),
  
  1. В файле views добавьте новую функцию. Вам нужно импортировать JsonResponse
 from django.http import JsonResponse

def change_privacy(request):
    if request.is_ajax() and request.method=='POST':

        profile = Profile.objects.get(user=request.user)

        profile.is_private = True if request.POST.get('is_private') == 'true' else False
        profile.save()
        data = {'status':'success', 'is_private':profile.is_private}
        return JsonResponse(data, status=200)
    else:
        data = {'status':'error'}
        return JsonResponse(data, status=400)
  

введите описание изображения здесь
введите описание изображения здесь

Комментарии:

1. @MrHize хорошо. Пожалуйста, объясните мне это. Вы пытаетесь сохранить при переключении переключателя ИЛИ отправляете форму после переключения этого переключателя?

2. Я хочу сохранить состояние при переключении. Я хочу, чтобы логическое поле по умолчанию было False (общедоступный профиль), поэтому, когда пользователь переключает логическое поле, оно становится True (частный профиль).

3. Спасибо за ваши ответы, но кода слишком много и он не упорядочен, я пробовал это, но работает не так, как я хочу. Я смог сделать логическое поле true или false в admin. Я не хочу этого, я хочу сделать логическое значение true или false во внешнем интерфейсе при нажатии. Пожалуйста, сделайте свой код понятным, просто сделайте его простым одним способом. Спасибо

4. @MrHize тогда вам нужно поработать только над частью Ajax и новой функцией change_privacy

5. @MrHize в представлении, которое показывает этот переключатель конфиденциальности, вам нужно передать is_privacy шаблону и снять флажок или галочку с переключателя. В этот файл шаблона добавьте Ajax. Чтобы статус менялся при переключении переключателя, вам необходимо отправить запрос через ajax

Ответ №2:

Вот как это сделать с помощью Ajax.

Сначала включите jQuery:

 <script src="https://code.jquery.com/jquery-3.5.1.min.js"
        integrity="sha256-9/aliU8dGd2tb6OSsuzixeV4y/faTqgFtohetphbbj0=" crossorigin="anonymous"></script>
  

При настройке Ajax вам необходимо включить токен CSRF (или украсить свой вид с помощью @csrf_exempt ). Соответствующий раздел в документации django. Если вы не включите токен CSRF в свой запрос, вы получите 403 Forbidden .

 <script type="text/javascript">
    function getCookie(name) {
        let cookieValue = null;
        if (document.cookie amp;amp; document.cookie !== '') {
            const cookies = document.cookie.split(';');
            for (let i = 0; i < cookies.length; i  ) {
                const cookie = cookies[i].trim();
                // Does this cookie string begin with the name we want?
                if (cookie.substring(0, name.length   1) === (name   '=')) {
                    cookieValue = decodeURIComponent(cookie.substring(name.length   1));
                    break;
                }
            }
        }
        return cookieValue;
    }

    const csrftoken = getCookie('csrftoken');
</script>
  

Затем выполните Ajax-запрос:

 <script type="text/javascript">
    $("document").ready(function () {
        $("#customSwitches").change(function () {
            $.ajax({
                type: "POST",
                headers: {
                    "X-CSRFToken": csrftoken
                },
                url: {% url 'privacy' %},
                data: {
                    "enabled": this.checked,
                },
                success: function (data) {
                    console.log(data);
                },
                error: function (data, msg) {
                    console.log("ERROR", data, msg);
                }
            });
        })
    });
</script>
  

Настройте URL-адрес для работы с вашим проектом и не забудьте включить токен CSRF в заголовок.

Затем вы можете получить значение флажка в своем представлении и обновить значение для вашего пользователя:

 def privacy_view(request):
    if request.is_ajax():
        enabled = request.POST["enabled"]
        profile = Profile.objects.get_or_create(user=request.user)
        profile.is_private = enabled
        profile.save()
    return render(request, "privacy.html")