I try copy my object.
I can receive copy from my "def checklist_copy" if i explicitly specify pk.(example)
But, i try work with 'self.pk' and this is not work. I want to copy the object under which I click on the button
i used different variations:
(pk=pk) in function,
checklist.id and checklist.pk in html template,
tried passing "self" to function and doing self.pk
doing pk=int(Checklist.object.get.id()) to then transfer this "pk" to (pk=pk) in object.id()
try include func in class DetailView
did not achieve a result
Please help. I don't know where and what to look for
Example:
models.py
from django.urls import reverse
from django.db import models
class Checklist(models.Model):
title = models.CharField(max_length=250)
def get_absolute_url(self):
return reverse ('checklist:checklist', kwargs={'id': self.id, 'title': self.title})
def __str__(self):
return self.title
view.py
from django.views.generic.list import ListView
from django.views.generic.detail import DetailView
from .models import Checklist
from django.shortcuts import redirect
from django.urls import reverse_lazy
class CheckListView(ListView):
model = Checklist
context_object_name = 'checklists'
class CheckListDetail(DetailView):
model = Checklist
context_object_name = 'checkList'
template_name = 'base/checklist.html'
def checklist_copy(request):
dest = Checklist.objects.get(pk=2) #here i need to use self.id(pk), but can't include 'self' in args of func
dest.pk = None
dest.save()
return redirect(reverse_lazy('checklists'))
urls.py (my app)
from django.urls import path
from .views import CheckListView, CheckListDetail
from . import views
urlpatterns = [
path('', CheckListView.as_view(), name='checklists'),
path('checklist/<int:pk>/', CheckListDetail.as_view(), name='checklist'),
path('checklist-copy/', views.checklist_copy, name='checklist_copy'),
]
checklist_list.html
<div id="tasklist" class="task-items-wrapper">
{% for checklist in checklists %}
<div class="task-wrapper" data-position="{{checklist.pk}}">
<div class="task-title">
{{checklist}}
</div>
</div>
<a class="task-wrapper" href="{% url 'checklist_copy' %}">Copy</a>
{% endfor %}
Related
I really dislike django CBV design which makes things without flexibility.
I would like to have a page whose upper part showing the content of objects and lower part has a form to be posted.
CBS formview
class EditStudent(FormView):
template_name = "editstudent.html"
model = models.Student
success_url = "/home"
Update:
I add the method but the error
'NoneType' object is not callable shows up.
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['students'] = Student.objects.all()[:5]
return context
How can I retriev objects of studens and show them on the template.
Thanks.
'NoneType' object is not callable: I get this error when I don't specify a form class. Created form class 'StForm' associated with model 'Student'.
In the EditStudent view class, the CreateView class was inherited, since the data was not saved to the database with the FormView.
Replace bboard with the name of the folder where your templates are placed.
I have this: templates/bboard which are in the application folder.
template_name = 'bboard/tam_form.html'
The success_url row specifies a path based on the path name.
success_url = reverse_lazy('student')
The five most recent records are also transmitted in the context.
context['students'] = Student.objects.order_by('-pk')[:5]
In the template, the first five records are displayed on top and a form is displayed below to fill out.
forms.py
from django.forms import ModelForm
from .models import Student
class StForm(ModelForm):
class Meta:
model = Student
fields = '__all__'
views.py
from .models import Student
from django.views.generic.edit import CreateView
from django.urls import reverse_lazy
from .forms import StForm
class EditStudent(CreateView):
template_name = 'bboard/editstudent.html'
form_class = StForm
success_url = reverse_lazy('student')
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['students'] = Student.objects.order_by('-pk')[:5]
return context
urls.py
from django.urls import path
from .views import *
urlpatterns = [
path('student/', EditStudent.as_view(), name='student'),
]
editstudent.html
<h4>
{% for aaa in students %}
<p>{{ aaa }}</p>
{% endfor %}
</h4>
<h2>form</h2>
<form method="post" action="{% url 'student' %}">
{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="adding">
</form>
I'm following along a book called Django for Beginners and creating a project which displays newspaper articles. Part of the functionality is being able to edit those articles. I've followed along as closely as I could but I'm still getting an error when hitting the 'Update' button:
My urls.py
from django.urls import path
from .views import (ArticleListView,
ArticleUpdateView,
ArticleDetailView,
ArticleDeleteView)
urlpatterns = [
path('<int:pk>/edit/', ArticleUpdateView.as_view(), name = 'article_edit'),
path('<int:pk>/', ArticleDetailView.as_view(), name = 'article_detail'),
path('<int:pk>/delete/', ArticleDeleteView.as_view(), name = 'article_delete'),
path('', ArticleListView.as_view(), name = 'article_list'),
]
my views.py
from django.shortcuts import render
from django.views.generic import ListView, DetailView
from django.views.generic.edit import UpdateView, DeleteView
from django.urls import reverse_lazy
from .models import Article
# Create your views here.
class ArticleListView(ListView):
model = Article
template_name = 'article_list.html'
class ArticleDetailView(DetailView):
model = Article
template_name = 'article_detail.html'
class ArticleUpdateView(UpdateView):
model = Article
fields = ('title', 'body')
template_name = 'article_edit.html'
class ArticleDeleteView(DeleteView):
model = Article
template_name = 'article_delete.html'
success_url = reverse_lazy('article_list')
My models.py:
from django.db import models
from django.conf import settings
from django.contrib.auth import get_user_model
from django.urls import reverse
# Create your models here.
class Article(models.Model):
title = models.CharField(max_length=225)
body = models.TextField()
date = models.DateTimeField(auto_now_add=True)
author = models.ForeignKey(
get_user_model(),
on_delete=models.CASCADE,
)
def __str__(self):
return self.title
def get_absolute_url(self):
reverse('article_detail', args=[str(self.id)])
My HTML:
<!-- templates/article_edit.html -->
{% extends 'base.html' %}
{% block content %}
<h1>Edit</h1>
<form action="" method="post">{% csrf_token %}
{{ form.as_p }}\
<button class="btn btn-info ml-2" type="submit">Update Article {{article.pk}}</button>
</form>
{% endblock content %}
After hitting the edit button, according to the book the app is supposed to forward me to the 'article_detail' page however that is not happening.
Any assistance would be gratefully received.
Thanks
Andy
In the end it was a simple omission of a return statement in the get_absolute_url function within models.py.
Hello I am new in Django, and I decided to do a Blog page. Problem is that my queryset is empty after I create a new aplication. any idea why ?
Tried with active and without active.
views.py
from django.shortcuts import render, get_object_or_404
from django.views.generic import ListView, DetailView
from django.http import Http404
from .models import BlogPost
class BlogPostListView(ListView):
queryset = BlogPost.objects.all().active()
template_name = "blog.html"
def get_queryset(self, *args, **kwargs):
request = self.request
return BlogPost.objects.all().active()
def BlogPost_list_view(request):
queryset = BlogPost.objects.all().active()
context = {
'object_blog': queryset
}
return render(request, "blog.html", context)
models.py
import random
import os
from django.db import models
from django.db.models.signals import pre_save, post_save
from django.urls import reverse
def get_filename_ext(filepath):
base_name = os.path.basename(filepath)
name, ext = os.path.splitext(base_name)
return name, ext
def upload_image_path(instance, filename):
print(instance)
print(filename)
new_filename = random.randint(1,18341264712)
name, ext = get_filename_ext(filename)
final_filename = '{new_filename}{ext}'.format(new_filename= new_filename, ext=ext)
return "products/{new_filename}/{final_filename}".format(
new_filename= new_filename,
final_filename=final_filename
)
class BlogPostQuerySet(models.query.QuerySet):
def active(self):
return self.filter(active=True)
def featured(self):
return self.filter(featured=True, active=True)
class BlogPostManager(models.Manager):
def get_queryset(self):
return BlogPostQuerySet(self.model, using=self._db)
def all(self):
return self.get_queryset()
class BlogPost(models.Model):
title = models.CharField(max_length=120)
slug = models.SlugField(blank=True, unique=True)
description = models.TextField()
image = models.ImageField(upload_to=upload_image_path, null=True, blank=True)
timestamp = models.DateTimeField(auto_now_add=True)
active = models.BooleanField(default=True)
objects = BlogPostManager()
def get_absolute_url(self):
return "{slug}/".format(slug=self.slug)
# return reverse("products:detail", kwargs={"slug": self.slug})
def __str__(self):
return self.title
def __unicode__(self):
return self.title
urls.py
from django.conf import settings
from django.conf.urls import url, include
from django.conf.urls.static import static
from .views import BlogPostListView, BlogPostDetailSlugView
urlpatterns = [
url(r'^$', BlogPostListView.as_view(), name='list'),
url(r'^(?P<slug>[-\w]+)/$', BlogPostDetailSlugView.as_view(), name='detail'),
]
if settings.DEBUG:
urlpatterns = urlpatterns + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
urlpatterns = urlpatterns + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
admin.py
from django.contrib import admin
from .models import BlogPost
class BlogPostAdmin(admin.ModelAdmin):
list_display = ['__str__', 'slug']
class Meta:
model = BlogPost
admin.site.register(BlogPost, BlogPostAdmin)
blog.html
{% for obj in object_blog %}
<!-- Blog Post -->
<div class="card mb-4 text-white bg-dark">
{% if obj.image %}
<!-- {{MEDIA_URL}} -->
<img class="card-img-top" src="{{ obj.image.url }}" alt="Card image cap">
{% else %}
<h1> No pic </h1>
{% endif %}
<div class="card-body">
<h2 class="card-title">{{ obj.title }}</h2>
<p class="card-text">{{ obj.description|slice:":255" }} ...</p>
Read More →
</div>
<div class="card-footer text-muted">
{{ obj.timestamp }}
Start Bootstrap
</div>
</div>
{% endfor %}
I am using almost the same pattern as I used in different application, where everything works. Few days ago I noticed some kind of strange bahavior from Django side, because it did want to show me images on the website, until I restarted a PC completely. If anyone needs more information / to see some different files, I can provide more. Here are few pictures from my Django admin.
Your two views BlogPostListView and BlogPost_list_view do almost exactly the same thing, I don't know why you have two of them. But note that the first one is the one that is actually used by your URL.
Now, that view is a class-based view that will send a variable called blog_list or object_list to the template. However, the template itself is iterating over a variable called object_blog, which would be sent by the (unused) second view. You should change that to object_list - or, in the view, you could add context_object_name = 'object_blog' (but I don't recommend that).
I have a section of my site where an admin can add a widget. However the delete button to delete any current widgets is not working. I have this code implemented else where on my site and it is working.
I copied the same code from the other section of my site where this is being used. The other section of my site which uses this code is a little different in that a post can only be deleted be the user who created it, and the widgets can be delete by any user with the "access_level" field is equal to "admin". However, I am the only admin so it should still work. The page that the widget stuff is displayed on is only accessible if your "access_level" is equal to admin so I don't need to validate whether or not they have the permission before deleting. Please help.
widget_list.html:
{% extends "base.html" %}
{% block content %}
<div class="container">
<div class="content">
<div class="widgets-list">
{% for widget in widget_list %}
<h3>{{ widget.name }}</h3>
<h3>{{ widget.widget_order }}</h3>
<div>
<p>{{ widget.body }}</p>
</div>
{% if user.is_authenticated %}
<a class="auth-user-options" href="{% url 'adminpanel:delete-widget' pk=widget.pk %}">Delete</a>
{% endif %}
{% endfor %}
</div>
</div>
</div>
{% endblock %}
Adminpanel app views.py:
from django.shortcuts import render
from adminpanel.forms import WidgetForm
from adminpanel.models import Widget
from django.utils import timezone
from django.contrib.auth import authenticate,login,logout
from django.http import HttpResponseRedirect, HttpResponse
from django.core.urlresolvers import reverse,reverse_lazy
from django.contrib.auth.decorators import login_required
from django.contrib.auth.mixins import LoginRequiredMixin
from braces.views import SelectRelatedMixin
from django.views.generic import (TemplateView,ListView,
DetailView,CreateView,
UpdateView,DeleteView)
# Create your views here.
class CreateWidgetView(LoginRequiredMixin,CreateView):
login_url = '/login/'
redirect_field_name = 'index.html'
form_class = WidgetForm
model = Widget
def form_valid(self,form):
self.object = form.save(commit=False)
self.object.save()
return super().form_valid(form)
def get_success_url(self):
return reverse('adminpanel:widgets')
class SettingsListView(ListView):
model = Widget
ordering = ['widget_order']
class DeleteWidget(LoginRequiredMixin,SelectRelatedMixin,DeleteView):
model = Widget
select_related = ('Widget',)
success_url = reverse_lazy('adminpanel:widget')
def get_queryset(self):
queryset = super().get_queryset()
return queryset.filter(user_id=self.request.user.id)
def delete(self,*args,**kwargs):
return super().delete(*args,**kwargs)
Project url spy:
from django.conf.urls import url
from django.contrib import admin
from django.conf.urls import include
from accounts import views
from colorsets import views
from colors import views
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^$',views.home,name='index'),
url(r'^accounts/',include('accounts.urls',namespace='accounts')),
url(r'^colorsets/',include('colorsets.urls',namespace='colorsets')),
url(r'^adminpanel/',include('adminpanel.urls',namespace='adminpanel')),
]
Adminpanel app urls.py:
from django.conf.urls import url
from adminpanel import views
app_name = 'adminpanel'
urlpatterns = [
url(r'^widgets/',views.SettingsListView.as_view(),name='widgets'),
url(r'^new/$',views.CreateWidgetView.as_view(),name='create-widget'),
url(r'^delete/(?P<pk>\d+)/$',views.DeleteWidget.as_view(),name='delete-widget'),
]
EDIT: Here is the error I'm getting I forgot to add it.
FieldError at /adminpanel/delete/10/
Cannot resolve keyword 'user_id' into field. Choices are: body, id, name, widget_order
and the traceback points to this:
/Users/garrettlove/Desktop/colors/adminpanel/views.py in get_queryset
return queryset.filter(user_id=self.request.user.id) ...
▶ Local vars
Adminpanel app models.py (widget model):
from django.db import models
from adminpanel.choices import *
# Create your models here.
class Widget(models.Model):
name = models.CharField(max_length=50)
widget_order = models.IntegerField(blank=False,unique=True)
display_name = models.IntegerField(choices=WIDGET_NAME_CHOICES,default=1)
body = models.TextField(max_length=500)
def __str__(self):
return self.name
As your error is saying:
Cannot resolve keyword 'user_id' into field.
And it points to this line:
return queryset.filter(user_id=self.request.user.id)
It's that your queryset model does not have a user_id field. In your DeleteWidget view you have specified model = Widget
and as you see in your Widget model, you have the following fields: body, id, name, widget_order. There is no user_id field.
You need to change your filtering logic. If you want to have a related User model, you should use ForeignKey relation and then you can filter by the User's id.
In your models.py:
from django.contrib.auth.models import User
class Widget(models.Model):
# ...
user = models.ForeignKey(User, on_delete=models.CASCADE)
And then in your DeleteWidget's get_queryset, you can do the following:
return queryset.filter(user__id=self.request.user.id)
# __________________________^
# Note that there is a double underscore here!
# This is because Django uses double underscore for accessing related models in queries.
I have been through all of the similar issues and I have gotten nowhere and I have gone through the djangogirls and the officail Django tutorials and as far as I can tell it should be working.
In the polls/templates/index.html file I have this:
[...]
{% if forms %}
<ul>
{% for form in forms %}
<li>
<h1><a href="{% url 'form_detail' pk=form.pk %}">
{{ form.fname }}
</a></h1>
[...]
In my polls/urls.py file I have this:
from django.conf.urls import url
from . import views
app_name = 'polls'
urlpatterns = [
[...]
url(r'^index/$', 'polls.views.site_index'),
[...]
url(r'^form/(?P<pk>\d+)/$', views.form_detail, name='form_detail'),
[...]
In my polls/views.py file I have this:
from django.shortcuts import render, render_to_response, redirect, get_object_or_404
from django.http import HttpResponse, HttpResponseRedirect
from django.core.context_processors import csrf
from django.core.urlresolvers import reverse
from django.contrib.auth.models import User
from .models import Nform, Choice, Question, Post
from django.template import loader
from django.utils import timezone
from django.views import generic
from django.contrib import auth
from django.db import models
from .form import PostForm
def site_index(request):
forms = Nform.objects.order_by('-published_date')
return render_to_response('polls/index.html', {'forms': forms})
def form_detail(request, pk):
current_form = get_object_or_404(Nform, pk=pk)
fame = current_form.fname
latest_question_list = Question.objects.filter(for_form=fame).order_by('-pub_date')
choice_quest_list = []
text_quest_list = []
form = PostForm()
for i in range(len(latest_question_list)):
if len(latest_question_list[i].choice_set.all()) == 0:
text_quest_list.append(latest_question_list[i])
else:
choice_quest_list.append(latest_question_list[i])
return render(request, 'polls/read_only.html', {'choice_quest_list': choice_quest_list, 'text_quest_list': text_quest_list, 'form_name': fame, 'form': form})
[...]
I am assume that I have made a very simple mistake somewhere and I would be very grateful to anyone who finds it.
See this issue for pics.
Here is a link to my code.
Thanks :)
This is happening because you have defined a variable named app_name in your application urls.py.
When you define that variable, it becomes your url namespace.
You either have to reverse your url like this:
<h1><a href="{% url 'polls:form_detail' pk=form.pk %}">
or remove the app_name variable to use the url name directly.
Read more about reversing url names # django-docs