I have a model called Publication and I'd like to add a button to the list view in Django Admin which would allow triggering a Celery task.
admin.py:
from django.contrib import admin
from .models import Publication
class PublicationAdmin(admin.ModelAdmin):
change_list_template = "variants/admin_publication_list.html"
def update(self, request):
# trigger task
# redirect to admin list
admin.site.register(Publication, PublicationAdmin)
variants/admin_publication_list.html:
{% extends 'admin/change_list.html' %}
{% block object-tools %}
<li>
<a href="/admin/variants/publication/update/">
Update
</a>
</li>
{{ block.super }}
{% endblock %}
However when I press a button I only get a notice:
Publication with ID “update” doesn’t exist. Perhaps it was deleted?
Method name update or route name update is too generic and sometimes used by frameworks automatically, try naming it to match your functionality. revoke-publications or sync-publications.
admin.py:
from django.contrib import admin
from django.urls import path
from django.http import HttpResponseRedirect
from .models import Publication
from .tasks import your_celery_task
#admin.register(Publication)
class PublicationAdmin(admin.ModelAdmin):
change_list_template = "variants/admin_publication_list.html"
def get_urls(self):
urls = super().get_urls()
my_urls = [
path('update-publications/', self.publication_update),
]
return my_urls + urls
def publication_update(self, request):
result = your_celery_task.delay("some_arg")
self.message_user(
request,
f"Task with the ID: {result.task_id} was added to queue. Last known status: {result.status}"
)
return HttpResponseRedirect("../")
variants/admin_publication_list.html:
{% extends 'admin/change_list.html' %}
{% block object-tools %}
<div>
<form action="update-publications/" method="POST">
{% csrf_token %}
<button type="submit">Run Celery Task</button>
</form>
</div>
<br />
{{ block.super }}
{% endblock %}
Related
I want to know the equivalent using <form action={% url '......' %}> in django-form(i.e. using forms.ModelForm class).
How do I define the action url of my form in djano-form? it can be easily done in HTML using action attribute of form as action={% url....
The form action in views.py will run when you click <button type='submit'> Submit </button> in your <form>. If it's not what you want:
That is how you can trigger a view function from html :
views.py
def YourAction(request, arg):
# do something
return redirect('/anywhere') # you need to return something
urls.py
from .views import YourAction
urlpatterns = [
path('dosomething/<arg>', YourAction, name='action_name'),
]
your html
<form action='{% url 'action_name' arg %}'>
<button type='submit'> Submit! </button>
</form>
You don't have to use form. You can just use <a href='{% url 'action_name' arg %}'> Do Something! </a>
You can change it, also, in View (views.py):
from django.urls import reverse
from .models import YOUR_FORM_MODEL
def myView(request):
if request. Method == 'GET':
form = YOUR_FORM_MODEL()
form.helper.form_action = reverse('appname:testme')
mydata = {'form': form}
return HttpResponse(render(request, 'appname/custom_page.html', context=mydata))
and add in Your urls.py:
from django.urls import path
from . import views
app_name = 'appname'
urlpatterns = [
path('test-my-custom-form-send-path', views.myView, name='testme'),
]
in your template (custom_page.html):
{% extends 'appname/base_html_file.html' %}{% load crispy_forms_tags %}{% load static %}
{% crispy form %}
Using quick_form Flask-Bootstrap to generate the form is very convenient for me, however, I could not find in their documentation a way that I can add extras class to label as required by my template theme.
My forms.py class look like this:
from flask_wtf import Form
from wtforms import StringField,PasswordField,TextField,SubmitField
from wtforms.validators import InputRequired,EqualTo,Email,ValidationError
class Building_Form(Form):
BuildingName = TextField('Building Name')
BuildingType = TextField('Building Type')
FloorNums = TextField('Numers of Floor')
BuildUnits = TextField('Units in Building')
BuildSize = TextField('Building Size')
BuiltYear = TextField('Built in (year)')
BuildOpeningTime = TextField('Open Time')
BuildClosingTime = TextField('Close Time')
My routes.py is like following:
from app.import_core import *
from flask_wtf import FlaskForm
from wtforms import Form, BooleanField, StringField, PasswordField, validators
from wtforms.validators import DataRequired
from flask_wtf.file import FileField, FileRequired
from werkzeug.utils import secure_filename
from werkzeug.security import generate_password_hash, check_password_hash
from .forms import Building_Form
# from app.user.models import TBL_USER
import pdb
#app.route('/building')
def show_building_listing():
return render_template('building_listing.html')
#app.route('/builing/new',methods=['GET','POST'])
def add_new_builing():
form = Building_Form()
if request.method=='POST':
return '<h1>Ok Building added</h1>'
return render_template('new_building.html',form=form)
My new_building.html to render a form:
{% extends "__dashboard.html" %}
{% import "bootstrap/wtf.html" as wtf %}
{% block include_css %}
<link rel="stylesheet" href="{{url_for('static',filename='css/login.css')}}">
<link rel="stylesheet" href="{{url_for('static',filename='css/bt-social-button/bootstrap-social.css')}}">
{% endblock %}
{% block content %}
<div class="card">
<div class="card-body">
{{ wtf.quick_form(form, extra_classes='bmd-label-floating') }}
</div>
</div>
{% endblock %}
I would like to add classes bmd-label-floating to my form label however it ended up with those classes in <form> instead.
How can I add that class my labels? Thanks.
I had a similar problem. A list of items was used to generate a form with multiple checkboxes. I needed to add a label class for styling them horizontally. I was able to loop through my form object and change class for the form field.label.
<form action="" method="post">
{% with test = form.example %}
{% for field in test %}
{{ field.label(class_='checkbox-inline') }}
{{ field }}
{% endfor %}
{% endwith %}
<p>{{ form.submit() }}</p>
</form>
I was following the django documentation and making a simple poll app. I have come across the following error :
Using the URLconf defined in mysite.urls, Django tried these URL patterns, in this order:
^polls/
^admin/
The current URL, , didn't match any of these."
settings.py
ROOT_URLCONF = 'mysite.urls'
mysite/mysite/urls.py
from django.conf.urls import include,url
from django.contrib import admin
urlpatterns = [
url(r'^polls/',include('polls.urls')),
url(r'^admin/', admin.site.urls),]
mysite/polls/urls.py
from django.conf.urls import url
from . import views
app_name= 'polls'
urlpatterns=[
url(r'^$',views.IndexView.as_view(),name='index'),
url(r'^(?P<pk>[0-9]+)/$',views.DetailView.as_view(), name='detail'),
url(r'^(?P<pk>[0-9]+)/results/$',views.ResultsView.as_view(),name='results'),
url(r'^(?P<question_id>[0-9]+)/vote/$',views.vote,name='vote'),]
mysite/polls/views.py
from django.shortcuts import get_object_or_404,render
from django.http import HttpResponseRedirect, HttpResponse
from django.core.urlresolvers import reverse
from django.views import generic
from django.utils import timezone
from django.template import loader
from .models import Choice,Question
from django.template.loader import get_template
#def index(request):
# return HttpResponse("Hello, world. You're at the polls index")
class IndexView(generic.ListView):
template_name='polls/index.html'
context_object_name='latest_question_list'
def get_queryset(self):
"""Return the last five published questions."""
return Question.objects.filter(pub_date__lte=timezone.now()).order_by('-pub_date')[5:]
class DetailView(generic.DetailView):
model=Question
template_name='polls/detail.html'
def get_queryset(self):
"""
Excludes any questions that aren't published yet.
"""
return Question.objects.filter(pub_date__lte=timezone.now())
class ResultsView(generic.DetailView):
model= Question
template_name ='polls/results.html'
def vote(request, question_id):
question=get_object_or_404(Question, pk=question_id)
try:
selected_choice= question.choice_set.get(pk=request.POST['choice'])
except (KeyError, Choice.DoesNotExist):
return render(request, 'polls/details.html',
{
'question':question,
'error_message' : "You didn't select a choice" ,
})
else:
selected_choice.votes+=1
selected_choice.save()
return HttpResponseRedirect(reverse('polls:results', args=(question.id,)))
index.html
<!DOCTYPE HTML >
{% load staticfiles %}
<html>
<body>
<link rel="stylesheet" type="text/css" href="{% static 'polls/style.css' %}" />
{% if latest_question_list %}
<ul>
{% for question in latest_question_list %}
<li><a href="{% url 'polls:detail' question.id %}">{{question.question_test }}
</a></li>
{% endfor %}
</ul>
{% else %}
<p>No polls are available.</p>
{% endif %}
</body>
</html>
This link http://127.0.0.1:8000/polls/ shows a blank page with 3 bullets. (I have 3 questions in my database and their id's are 5,6,7 because I have been deleting and adding the questions.)
My admin works fine!
I'm new to Django and have been searching and asking around and have been stuck on it for a while now.
You get the 404 on http://127.0.0.1:8000/ because you have not created any URL patterns for that url. You have included the url http://127.0.0.1:8000/polls/, because you have included the polls urls with
url(r'^polls/',include('polls.urls')),
The empty bullets suggest that there is a problem with your polls/index.html template. It looks like you have a typo and have put {{ question.question_test }} instead of {{ question.question_text }}. Make sure that it exactly matches the template from the tutorial 3:
{% if latest_question_list %}
<ul>
{% for question in latest_question_list %}
<li>{{ question.question_text }}</li>
{% endfor %}
</ul>
{% else %}
<p>No polls are available.</p>
{% endif %}
Make sure there is no typo in your code. Putting space between inverted commas can also lead to this error. Just make sure you have put path('',include('home.urls')) and not path(' ',include('home.urls'))
Note: here home.urls is the name of my app in Django
I was following the django documentation and making a simple poll app. I have come across the following error :
Using the URLconf defined in mysite.urls, Django tried these URL patterns, in this order:
^polls/
^admin/
The current URL, , didn't match any of these."
settings.py
ROOT_URLCONF = 'mysite.urls'
mysite/mysite/urls.py
from django.conf.urls import include,url
from django.contrib import admin
urlpatterns = [
url(r'^polls/',include('polls.urls')),
url(r'^admin/', admin.site.urls),]
mysite/polls/urls.py
from django.conf.urls import url
from . import views
app_name= 'polls'
urlpatterns=[
url(r'^$',views.IndexView.as_view(),name='index'),
url(r'^(?P<pk>[0-9]+)/$',views.DetailView.as_view(), name='detail'),
url(r'^(?P<pk>[0-9]+)/results/$',views.ResultsView.as_view(),name='results'),
url(r'^(?P<question_id>[0-9]+)/vote/$',views.vote,name='vote'),]
mysite/polls/views.py
from django.shortcuts import get_object_or_404,render
from django.http import HttpResponseRedirect, HttpResponse
from django.core.urlresolvers import reverse
from django.views import generic
from django.utils import timezone
from django.template import loader
from .models import Choice,Question
from django.template.loader import get_template
#def index(request):
# return HttpResponse("Hello, world. You're at the polls index")
class IndexView(generic.ListView):
template_name='polls/index.html'
context_object_name='latest_question_list'
def get_queryset(self):
"""Return the last five published questions."""
return Question.objects.filter(pub_date__lte=timezone.now()).order_by('-pub_date')[5:]
class DetailView(generic.DetailView):
model=Question
template_name='polls/detail.html'
def get_queryset(self):
"""
Excludes any questions that aren't published yet.
"""
return Question.objects.filter(pub_date__lte=timezone.now())
class ResultsView(generic.DetailView):
model= Question
template_name ='polls/results.html'
def vote(request, question_id):
question=get_object_or_404(Question, pk=question_id)
try:
selected_choice= question.choice_set.get(pk=request.POST['choice'])
except (KeyError, Choice.DoesNotExist):
return render(request, 'polls/details.html',
{
'question':question,
'error_message' : "You didn't select a choice" ,
})
else:
selected_choice.votes+=1
selected_choice.save()
return HttpResponseRedirect(reverse('polls:results', args=(question.id,)))
index.html
<!DOCTYPE HTML >
{% load staticfiles %}
<html>
<body>
<link rel="stylesheet" type="text/css" href="{% static 'polls/style.css' %}" />
{% if latest_question_list %}
<ul>
{% for question in latest_question_list %}
<li><a href="{% url 'polls:detail' question.id %}">{{question.question_test }}
</a></li>
{% endfor %}
</ul>
{% else %}
<p>No polls are available.</p>
{% endif %}
</body>
</html>
This link http://127.0.0.1:8000/polls/ shows a blank page with 3 bullets. (I have 3 questions in my database and their id's are 5,6,7 because I have been deleting and adding the questions.)
My admin works fine!
I'm new to Django and have been searching and asking around and have been stuck on it for a while now.
You get the 404 on http://127.0.0.1:8000/ because you have not created any URL patterns for that url. You have included the url http://127.0.0.1:8000/polls/, because you have included the polls urls with
url(r'^polls/',include('polls.urls')),
The empty bullets suggest that there is a problem with your polls/index.html template. It looks like you have a typo and have put {{ question.question_test }} instead of {{ question.question_text }}. Make sure that it exactly matches the template from the tutorial 3:
{% if latest_question_list %}
<ul>
{% for question in latest_question_list %}
<li>{{ question.question_text }}</li>
{% endfor %}
</ul>
{% else %}
<p>No polls are available.</p>
{% endif %}
Make sure there is no typo in your code. Putting space between inverted commas can also lead to this error. Just make sure you have put path('',include('home.urls')) and not path(' ',include('home.urls'))
Note: here home.urls is the name of my app in Django
I was changing some views earlier related to some geolocation (that failed) and upon restoring the previous views, I'm receiving this error:
TemplateSyntaxError at /report/all/
Caught NoReverseMatch while rendering: Reverse for 'profiles_profile_detail' with arguments '('',)' and keyword arguments '{}' not found.
What's odd is that the views I altered and restored had nothing to do with this view or template. The urls.py file was not touched at all. All other pages in the application are displaying normally. I can't figure out what the problem might be.
Views:
from django.http import HttpResponse, HttpResponseRedirect, Http404
from django.shortcuts import render_to_response, get_object_or_404, redirect
from django.template import RequestContext
from django.core.urlresolvers import reverse
from myapp.report.models import Story, UserProfile
from myapp.report.forms import ProfileForm, StoryForm
from django.contrib.auth.decorators import login_required
from django.contrib.gis.utils import GeoIP
def all_stories(request):
if not request.user.is_authenticated():
return redirect("django.contrib.auth.views.login")
all_stories = Story.objects.all().order_by("-date")
return render_to_response("report/storyline.html",
{'stories': all_stories},
context_instance=RequestContext(request))
def story_detail(request, story_id):
story = get_object_or_404(Story, id=story_id)
return render_to_response('report/detail.html',
{'story': story},
context_instance=RequestContext(request))
#login_required
def submit_story(request):
if request.method =="POST":
story_form = StoryForm(request.POST, request.FILES)
if story_form.is_valid():
new_story = story_form.save(commit=False)
new_story.author = request.user
new_story.save()
return HttpResponseRedirect("/report/all/")
else: # GET request
story_form = StoryForm()
return render_to_response("report/report.html", {'form': story_form}, context_instance=RequestContext(request))
Forms (changed but restored; appear to be working):
from django import forms
from stentorian.report.models import UserProfile, Story
from django.contrib.gis.utils import GeoIP
class ProfileForm(forms.ModelForm):
class Meta:
model = UserProfile
class StoryForm(forms.ModelForm):
class Meta:
model = Story
exclude = ('author',)
Template:
{% extends 'base.html' %}
{% block page_title %}Stentorian{% endblock %}
{% block headline %}Stentorian Storyline{% endblock %}
{% block content %}
<div class="row">
<div class="span12">
<h2>Welcome {{ user.username }}</h2>
<div class="accordion" id="story_accordion">
{% for story in stories %}
<div class="accordion-group">
<div class="accordion-heading">
<a class="accordion-toggle story-header" data-toggle="collapse" data-parent="#story_accordion" href="#story_{{ story.id }}">
{{ story.title }} - {{ story.author.username }} - {{ story.date }}
</a>
</div>
<div id="story_{{ story.id }}" class="accordion-body collapse{% if forloop.counter0 == 0 %} in{% endif %}">
<div class="accordion-inner">
<!-- <h2>{{story.title}}</h2>-->
<span>{{story.author}} </span><br>
<span>{{story.topic}}</span><br>
<span>{{story.zip_code}}</span><br>
<span>{{story.date}}</span><br>
<p>{{story.copy}}</p>
</div>
</div>
</div>
<br>
{% endfor %}
</div>
</div>
</div>
{% endblock content %}
The error is coming up on the line:
{% for story in stories %}
If anyone can provide an idea of why this is happening, it would be most appreciated. Again, the url wasn't changed, which seems to be the chief reason for this error.
Seems like u r not getting user.username
Try with this.
<h2>Welcome {{ request.user.username }}</h2>