#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, то должно быть указано соответствующее имя, указанное в классе Form2. @AchuthVarghese… Спасибо за это понимание. Можете ли вы помочь мне с views.py ? Я не нашел никакого руководства о том, как переключать логическое поле в Django
3. Зачем нужен order_by в вашей функции views? Был бы только один профиль, соответствующий пользовательскому праву.
Ответ №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>
- Добавьте новый путь в свой файл urls приложения, который привязывается к представлению. Скажите: функция, названная
change_privacy()
в ваших представлениях
path('changeprivacy', change_privacy, name="change_privacy"),
- В файле 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")