I have a little issue. For example, I have this view:
def post_create(request):
form = PostForm(request.POST or None)
if form.is_valid():
instance = form.save(commit=False)
instance.save()
# message success
messages.success(request, "Successfully Created")
return HttpResponseRedirect(instance.get_absolute_url())
else:
messages.error(request, "Not Successfully Created")
context = {
"form": form,
}
return render(request, "post_form.html", context)
Main problem: after redirect I have both messages (if and else at the same time). WHY?
Solution is:
... ...
return HttpResponseRedirect(instance.get_absolute_url())
elif form.errors:
messages.error(request, "Not Successfully Created")
context = {
"form": form,
}
return render(request, "post_form.html", context)
But why I see both of messages when I redirect after success validation (1st variant)?
base.html:
{% load staticfiles %}
<!--DOCTYPE html -->
<html>
<head>
<title></title>
<link rel='stylesheet' href='{% static "css/base.css" %}' />
<style>
{% block style %}{% endblock style %}
</style>
</head>
<body>
{% include "messages_display.html" %}
<div class='container'>
{% block content %}{% endblock content %}
</div>
</body>
</html>
messages_display.html:
{% if messages %}
<div class='messages'>
<ul class="messages">
{% for message in messages %}
<li{% if message.tags %} class="{{ message.tags }}"{% endif %}>{% if "html_safe" in message.tags %}{{ message|safe }}{% else %}{{ message }}{% endif %}</li>
{% endfor %}
</ul>
</div>
{% endif %}
post_form.html:
{% extends "base.html" %}
{% block content %}
<div class='col-sm-6 col-sm-offset-3'>
<h1>Form</h1>
<form method='POST' action=''>{% csrf_token %}
{{ form.as_p }}
<input type='submit' class='btn btn-default' value='Create Post' />
</form>
</div>
{% endblock content %}
Related
One of functionality in my training project:
subscribe to the news by check-box and e-mail.
Send newsletter daily.
The user can unsubscribe from the mailing list in his profile by unchecking the checkbox.
It so happened that first I set up a daily newsletter for users who have booleanfield = true.
For it I marked the checkboxes in the admin panel. It works.
Now it is necessary to add the checkbox and the mail field to the news page.
I'm stuck on the simplest. Tired and confused.
Please help me place a checkbox and a mail box with a send button on the news page
models.py
class Profile(models.Model):
user = models.OneToOneField(settings.AUTH_USER_MODEL,
on_delete=models.CASCADE)
hr = models.BooleanField(default=False)
subscribed_for_mailings = models.BooleanField(default=False)
subscription_email = models.EmailField(default="")
def __str__(self):
return str(self.user)
Forms.py
class MailingForm(forms.ModelForm):
class Meta:
model = models.Profile
fields = ('subscription_email', 'subscribed_for_mailings', )
widgets = {
'subscription_email': forms.EmailInput(attrs={"placeholder": "Your Email..."}),
'subscribed_for_mailings': forms.CheckboxInput,
}
views.py
def all_news(request):
today = date.today()
today_news = models.TopNews.objects.filter(created__gte=today)
return render(request, "news.html",
{'today_news': today_news})
def mailing_news(request):
if request.method == 'POST':
mailing_form = forms.MailingForm(request.POST)
if mailing_form.is_valid():
mailing_form.save()
return HttpResponse('You will receive news by mail')
else:
mailing_form = forms.MailingForm()
return render(request, "news.html", {'mailing_form': mailing_form})
urls.py
...
path('news/', views.all_news, name='all_news'),
...
news.html
{% extends 'base.html' %}
{% block title %}
News
{% endblock %}
{% block body %}
<h1>Last news</h1>
{% for news in today_news%}
<h3>{{ news.title }}</h3>
Read this news
<p>
{{ news.created }}
</p>
<hr>
{% endfor %}
<h4>I want to receive news by mail</h4>
<form action="." method="post">
{{ mailing_form.as_p }}
{% csrf_token %}
<label>
<input type="submit" value="Subscribe">
</label>
</form>
{% endblock %}
The page displays a list of news and only the "send" button. There is no check-box and a field for mail
enter image description here
Finally I realized this functionality in a different way:
forms.py
class MailingForm(forms.ModelForm):
class Meta:
model = models.Profile
fields = ('subscribed_for_mailings', 'subscription_email', )
views.py
#login_required
def mailing_news(request):
if request.method == "POST":
mailing_form = forms.MailingForm(request.POST,
instance=request.user.profile,
)
if mailing_form.is_valid():
mailing_news = mailing_form.save(commit=False)
mailing_news.subscribed_for_mailings = mailing_news.subscribed_for_mailings
mailing_news.subscription_email = mailing_news.subscription_email
mailing_news.save()
return render(request, "subscribe_complete.html",
{"mailing_news": mailing_news})
else:
mailing_form = forms.MailingForm()
return render(request, 'subscribe.html', {"mailing_form": mailing_form})
news.html
{% extends 'base.html' %}
{% block title %}
News
{% endblock %}
{% block body %}
<h1>Last news</h1> {{ news.created }}
{% for news in today_news%}
<h3>{{ news.title }}</h3>
Read this news
<hr>
{% endfor %}
I want to receive news by mail
{% endblock %}
urls.py
...
path('subscribe/', views.mailing_news, name='subscribe')
...
news.html
{% extends 'base.html' %}
{% block title %}
News
{% endblock %}
{% block body %}
<h1>Last news</h1> {{ news.created }}
{% for news in today_news%}
<h3>{{ news.title }}</h3>
Read this news
<hr>
{% endfor %}
I want to receive news by mail
{% endblock %}
subscribe.html
{% extends 'base.html' %}
{% block title %}
Subscribe
{% endblock %}
{% block body %}
<form action="." method="post" enctype="multipart/form-data">
{% csrf_token %}
{{ mailing_news.as_p }}
{% if user.profile.subscribed_for_mailings is True %}
<input type="checkbox" name="subscribed_for_mailings" id="id_subscribed_for_mailings" checked="">
If you don't want to receive emails anymore, uncheck
<br>
Subscription email: <input type="email" name="subscription_email" value={{ user.profile.subscription_email }} class="vTextField" maxlength="254" id="id_subscription_email">
{% else %}
<label>
<input type="checkbox" name="subscribed_for_mailings" id="id_subscribed_for_mailings">
I want to subscribe for mailing news
</label>
<p><label>
Send news on my email:
<input type="email" name="subscription_email" class="vTextField" maxlength="254" id="id_subscription_email">
</label></p>
{% endif %}
<p><input type="submit" value="Update"></p>
</form>
{% endblock %}
subscribe_complete.html
{% extends 'base.html' %}
{% block title %}
Subscribing complete
{% endblock %}
{% block body %}
<h3>Hi {{ user.username }}</h3>
Thanks for subscribing.
You will receive daily news by email: {{ user.profile.subscription_email }}
{% endblock %}
you need to change subscribed_for_mailings in mailing news, like this
def mailing_news(request):
if request.method == 'POST':
mailing_form = forms.MailingForm(request.POST)
if mailing_form.is_valid():
profile = mailing_form.save(commit=False) ####
profile.subscribed_for_mailings = mailing_form.cleaned_data.get('subscribed_for_mailings') ####
profile.subscription_email = mailing_form.cleaned_data.get('subscription_email') ####
profile.save() #### new_line
return HttpResponse('You will receive news by mail')
else:
mailing_form = forms.MailingForm()
return render(request, "news.html", {'mailing_form': mailing_form})
you can change in cleaned_data.get('....')
I've created my own message engine on Django framework to let users send messages to each others, here is my message model
models.py
class Message(models.Model):
sender = models.ForeignKey(UserModel, related_name="sender", on_delete='CASCADE')
receiver = models.ForeignKey(UserModel, related_name="receiver", on_delete='CASCADE')
msg_title = models.CharField(max_length=150, verbose_name='عنوان الرسالة', default='رسالة جديدة من مستخدم فوستانيا')
msg_content = models.TextField(max_length=1200,verbose_name='محتوى الرسالة')
created_at = models.DateTimeField(auto_now=True)
read = models.BooleanField(default=False)
Then am listing messages for the user, they can see the messages with read=False as a new message, they are able to click it to see the full message, I want the read status to be changed to True after the user clicks the message from the template,, How to do it!
urls.py
path('messages/', views.messages, name="messages"),
path('messages/<int:pk>/', views.message_page, name="message_page"),
views.py
#login_required
def messages(request):
inbox = Message.objects.filter(receiver=request.user, read=True)
context = {
'inbox': inbox,
}
return render(request, 'fostania_web_app/messages.html', context)
def message_page(request, pk):
current_msg = get_object_or_404(Message, pk=pk)
context = {
'current_msg': current_msg,
}
return render(request, 'fostania_web_app/message_page.html', context)
Message list template message.html
{% extends 'fostania_web_app/base.html' %}
{% block content %}
{% load static %}
{% if user.is_authenticated %}
<br><br>
<div class="card text-white bg-warning mb-3" style="max-width: 75rem;" align="right">
<div class="card-header">رسائل جديدة </div>
<div class="card-body">
<p class="card-text">
{% if new_messages.count != 0 %}
{% for msg in new_messages %}
<img src="{% static 'img/new-msg.png' %}"> {{ msg.msg_title }}
<br>
{% endfor %}
{% else %}
لا توجد رسائل غير مقروءة
{% endif %}
</p>
</div>
</div>
<!-- old msgs -->
<div class="card text-dark bg-ligh mb-3" style="max-width: 75rem;" align="right">
<div class="card-header"><img src="{% static 'img/inbox.png' %}"> صندوق الوارد </div>
<div class="card-body">
<p class="card-text">
{% for msg in inbox %}
<img src="{% static 'img/old-msg.png' %}"> {{ msg.msg_title }}<br>
{% endfor %}
</p>
</div>
</div>
{% else %}
يتوجب عليك تسجيل الدخول اولاً
{% endif %}
{% endblock %}
Message body after clicking and passing it's pk message_page.html
{% extends 'fostania_web_app/base.html' %}
{% block content %}
{% load static %}
<Br><br>
<div class="card bg-light mb-3" style="max-width: 50rem;" align="right ">
<div class="card-header">{{ current_msg.sender.name }}</div>
<div class="card-body">
<h5 class="card-title">{{ current_msg.msg_title }}</h5>
<p class="card-text">{{ current_msg.msg_content }}
<Br><br>
<button class="btn btn-success">إرسـال رد</button>
<button class="btn btn-danger">رجوع للرسائل </button>
</p>
</div>
</div>
{% endblock %}
You can avoid too much work by simply updating the message being read:
def message_page(request, pk):
current_msg = get_object_or_404(Message, pk=pk)
current_msg.read = True
current_msg.save()
context = {
'current_msg': current_msg,
}
return render(request, 'fostania_web_app/message_page.html', context)
BONUS:
instead of
{% if new_messages.count != 0 %}
{% for msg in new_messages %}
''' '''
{% endfor %}
{% else %}
لا توجد رسائل غير مقروءة
{% endif %}
Inside the loop, you can check whether the msg is read or not rather than send one more queryset, so you can simply do
{% for msg in new_messages %} # instead of new_messages, send all_messages
{% if msg.read %}
''' old message '''
{% else %}
''' new message '''
{% endif %}
{% empty %}
لا توجد رسائل غير مقروءة # don't really know what does that mean
{% endfor %}
I am writing a very simple navigation bar. For example I have my login view down below. When I open the login page I can see my the results of my base.html but for some reason I can not see the results of my login.html, meaning I cant see the form I wrote only the top links bar.
view.py -- login view
def login(request):
if request.method == 'POST':
form = UserLoginForm(request.POST)
if form.is_valid():
m = UserLogin.objects.get(user_name=request.POST['user_name'])
if m.password == request.POST['password']:
request.session['member_id'] = m.id
return HttpResponseRedirect('/game')
else:
c = {'form': form,
'error_message': "Your username and password didn't match."}
c.update(csrf(request))
return render_to_respons('game/login.html', c)
else:
form = UserLoginForm()
c = {'form': form}
c.update(csrf(request))
return render_to_response('game/login.html', c)
base.html
<div id="navigation">
Home
Upload
Register
Login
</div>
login.html
{% extends "base.html" %}
{% if error_message %}<p><strong>{{ error_message }}</strong></p>{% endif %}
<form action="/game/login/" method="post">
{% csrf_token %}
<table border='0'>
<div class="fieldWrapper"><tr><td>
{{ form.user_name.errors }}</td><td></td></tr><tr><td>
<label for="id_user_name">User Name:</label></td><td>
{{ form.user_name }}</td></tr>
</div>
<div class="fieldWrapper"><tr><td>
{{ form.password.errors }}</td><td></td><tr><td>
<label for="id_password">Password:</label></td><td>
{{ form.password }}</td></tr>
</div>
</table>
<input type="submit" value="Login" />
</form>
You need to define blocks to use template inheritance. For example, change your base.html to:
<div id="navigation">
Home
Upload
Register
Login
</div>
{% block content %}{% endblock %}
then place your login code into the content block:
{% extends "base.html" %}
{% block content %}
...login.html content goes here
{% endblock %}
Check out the docs for more detail.
I'm doing a function to upload a file with a example that I found here on Stack Overflow, everything works fine, the problem is that when I try to access the document by a URL, the click sends me to the app url not the photo url, for example I'm trying to access to this
http://localhost:8000/media/documents/2013/10/01/Desert.jpg
and it should be the image URL
documents/2013/10/01/Desert.jpg
view.py
def list(request):
# Handle file upload
if request.method == 'POST':
form = DocumentForm(request.POST, request.FILES)
print form
if form.is_valid():
newdoc = Document(docfile=request.FILES['docfile'],credencial_miembro=request.POST['credencial_miembro'])
print newdoc
newdoc.save()
# Redirect to the document list after POST
return HttpResponseRedirect(reverse('expmedico.views.list'))
else:
form = DocumentForm() # A empty, unbound form
# Load documents for the list page
documents = Document.objects.all()
# Render list page with the documents and the form
return render_to_response(
'upload.html',
{'documents': documents, 'form': form},
context_instance=RequestContext(request)
)
forms.py
class DocumentForm(forms.Form):
docfile = forms.FileField(
label='Select a file',
help_text='max. 42 megabytes'
)
credencial_miembro=forms.CharField(max_length=20)
model.py
class Document(models.Model):
docfile = models.FileField(upload_to='documents')
credencial_miembro= models.CharField(max_length=20,null=False, blank=False)
ulr
url(r'^list/$', 'expmedico.views.list',name='list'),
Setting.py
MEDIA_ROOT = os.path.join(RUTA_PROYECTO, 'media')
MEDIA_URL = '/media/'
template.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Minimal Django File Upload Example</title>
</head>
<body>
<!-- List of uploaded documents -->
{% if documents %}
<ul>
{% for document in documents %}
<li>{{ document.docfile.name }}</li>
{% endfor %}
</ul>
{% else %}
<p>No documents.</p>
{% endif %}
<!-- Upload form. Note enctype attribute! -->
<form action="{% url list %}" method="post" enctype="multipart/form-data">
{% csrf_token %}
<table style="width:150%;">
<div style="text-align:center; font-style: oblique; color: red" >
{% if messages %}
<ul class="messages">
{% for message in messages %}
<li{% if message.tags %} class="{{ message.tags }}"{% endif %}><b>{{ message }}</b></li>
{% endfor %}
</ul>
{% endif %}
</div>
<tr>
<td><label>Fecha:</label></td>
<td>
<output><b>{% now "D d M Y" %}</b></output>
</td>
<td>{{ form.credencial_miembro.errors }}<label>Credencial:</label></td>
<td>{{ form.credencial_miembro }} </td>
</tr>
</table>
<p>{{ form.non_field_errors }}</p>
<p>{{ form.docfile.label_tag }} {{ form.docfile.help_text }}</p>
<p>
{{ form.docfile.errors }}
{{ form.docfile }}
</p>
<p><input type="submit" value="Upload" /></p>
</form>
</body>
</html>
You are accessing a model not an image. Also, this might help:
https://docs.djangoproject.com/en/1.2/howto/static-files/
Please take a look there as i don't see this added to the urls.py you pasted.
I'm working on a project and we need to add a form to add an event. It lists the name, date, time, and address. I got the form to work but when I added the base, the form doesn't show up on the web page with the base loaded. I'm thinking it has something to do with my html file. Here is my html file.
{% extends "base.html" %}
{% block heading %}My Events{% endblock %}
{% block content3 %}
</h1><b><font size="5">Save Event</b></h1></font>
<form method="POST" action=".">{% csrf_token %}
{{form.as_p}}
<input type ="submit" value="Add Event"/>
</form>
{% endblock %}
views:
def add_event(request):
user = request.user
events = user.event_set.all()
if request.method == "POST":
form = EventForm(request.POST)
if form.is_valid():
event = Event.objects.create(
eventname = form.cleaned_data['eventname'],
eventdate = form.cleaned_data['eventdate'],
eventtime = form.cleaned_data['eventtime'],
address = form.cleaned_data['address'],
user = request.user
)
return HttpResponseRedirect('/')
else:
form = EventForm()
variables = RequestContext(request, {
'form': form
})
return render_to_response('add_event.html',variables)
base:
HTML (base.html)
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
<title>DelMarVa Happenings | {% block title %}{% endblock %}</title>
<link rel="stylesheet" href="/site_media/style.css" type="text/css" />
</head>
<body>
<div id="wrapper">
<div id="masthead">
<div id="logo">
<img src="/site_media/Delmarva.gif" width="100px" height="80px" />
</div>
<h1>DelMarVa Happenings</h1>
<br />
<h4>A listing of events in and around Delaware, Maryland, and Virginia</h4>
</div>
<div id="nav">
{% if user.is_authenticated %}
<h3>welcome, {{ user.username }}</h3>
{% else %}
<h3>welcome, guest</h3>
{% endif %}
<ul>
<li><a href="/">home<a/></li>
{% if user.is_authenticated %}
<li>add event</li>
<li>my events</li>
<li>my account</li>
<li>logout</li>
{% else %}
<li>login</li>
<li>register</li>
{% endif %}
</ul>
</div>
<div id="ads">
<img src="/site_media/ad.jpg" />
</div>
<div id="main">
<h2>{% block head %}{% endblock %}</h2>
{% block content %}{% endblock %}
</div>
</div>
</body>
</html>
Your base.html does not have a {% block content3 %} - rename the block name in base, or the extended template to match each other.
Make sure to leave space between form.as_p and the braces. As such, {{ form.as_p }}