django about deleteview and view - python

I am creating a bulletin board that communicates by DB <> API <> WEB method.
I want to create a view to delete comments, but an Improperly Configured error occurs when I request to delete comments from the web. Can I define a query set without Model,DB? Or is my code a problem? Which view should I use?
Improperly Configured Error with deleteview, Method not allowed with view
generic.deleteview
view
WEB view.py
class Commentapi_delete(generic.DeleteView):
def delete(self, request, *args, **kwargs):
datas = {
'pk': self.kwargs['pk'],
'id': self.kwargs['id']
}
url = 'http://127.0.0.1:8080/boardapi/' + str(datas['pk']) + '/comment/' + str(datas['id']) + '/delete/'
c_delete = requests.delete(url, params=datas)
print(datas)
print(c_delete)
return redirect(reverse('board_detail', kwargs={'pk': self.kwargs['pk']}))
API view.py
class CommentUpdateDeleteView(generics.RetrieveUpdateDestroyAPIView):
model = Comment
queryset = Comment.objects.all()
serializer_class = CommentSerializer
EDIT
WEB view.py
class Commentapi_delete(generic.DeleteView):
def get(self, request, *args, **kwargs):
data ={
'pk': self.kwargs['pk'],
'id': self.kwargs['id']
}
url = 'http://127.0.0.1:8080/boardapi/' + str(data['pk']) + '/comment/'
c_get = requests.get(url, params=data)
return **What shoud i return?**
def post(self, request, *args, **kwargs):
datas = {
'pk': self.kwargs['pk'],
'id': self.kwargs['id']
}
url = 'http://127.0.0.1:8080/boardapi/' + str(datas['pk']) + '/comment/' + str(datas['id']) + '/delete/'
c_delete = requests.delete(url, params=datas)
print(datas)
print(c_delete)
return redirect(reverse('board_detail', kwargs={'pk': self.kwargs['pk']}))
html
<form action="{% url 'comment_delete' %}" method="POST">
{% csrf_token %}
<td style="vertical-align: top;border-top: 1px solid #eee;padding: 10px 0;padding-right: 5px;" align="right" width="10%">
<button class="btn btn-outline-success my-2 my-sm-0" style="margin-right:10px;">Delete</button>
</td>
</form>
</tr>
</tbody>
</table>
{% endfor %}
</div>
<div>
<form method="POST">
{% csrf_token %}
<table width="100%" cellpadding="0" cellspacing="0">
<tr style="height:45px;border-top:solid 1px #dddddd;">
<td width="20%" align="left" style="vertical-align: top; padding-top: 10px;"><input type="input" name="c_writer" placeholder="writer" /></td>
<td width="80%" align="left" style="vertical-align: top; padding-top: 10px;"><textarea name="c_note" rows="4"></textarea></td>
</tr>
</table>
<div>
<button class="btn btn-outline-success my-2 my-sm-0" style="margin-right:10px;">save</button>
</div>
</form>
Error

The generic.DeleteView seems to be the correct one, but you haven't defined your queryset, you did so in your CommentUpdateDeleteView(generics.RetrieveUpdateDestroyAPIView), u should either define you queryset in a similar way on your Commentapi_delete(generic.DeleteView) or override the get_queryset method on the class to return you own desired queryset.

Related

Django No Reverse Match Error - Nothing is working

When rendering a new page, the html form action on that new page is stopping the page from being rendered... even though it has nothing to do with the page itself being rendered (if I remove that one line of HTML code, the page loads just fine). I've been working on solving this problem for over 3 days, tried hundreds of possible solutions, nothing works. Please help
This is the error:
NoReverseMatch at /newgallery/rodneyadmin
Reverse for 'editgallery' with arguments '('rodneyadmin', '')' not found. 1 pattern(s) tried: ['editgallery/(?P<username>[^/]+)/(?P<new_gallery>[0-9]+)\\Z']
Request Method: GET
Request URL: http://127.0.0.1:8000/newgallery/rodneyadmin
Django Version: 4.0
Exception Type: NoReverseMatch
Exception Value:
Reverse for 'editgallery' with arguments '('rodneyadmin', '')' not found. 1 pattern(s) tried: ['editgallery/(?P<username>[^/]+)/(?P<new_gallery>[0-9]+)\\Z']
Exception Location: /Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/django/urls/resolvers.py, line 729, in _reverse_with_prefix
Python Executable: /Library/Frameworks/Python.framework/Versions/3.9/bin/python3
Python Version: 3.9.7
Python Path:
['/Users/rodneyrussell/Desktop/github/Capstone/Capstone',
'/Library/Frameworks/Python.framework/Versions/3.9/lib/python39.zip',
'/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9',
'/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/lib-dynload',
'/Users/rodneyrussell/Library/Python/3.9/lib/python/site-packages',
'/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages']
Server time: Thu, 10 Feb 2022 16:41:21 -0500
Error during template rendering
In template /Users/rodneyrussell/Desktop/github/Capstone/Capstone/templates/galleries/newgallery.html, error at line 21
Reverse for 'editgallery' with arguments '('rodneyadmin', '')' not found. 1 pattern(s) tried: ['editgallery/(?P<username>[^/]+)/(?P<new_gallery>[0-9]+)\\Z']
11 Create new gallery
12 </h1>
13 </div>
14 </div>
15
16
17 <div class="row mb-3 d-flex justify-content-center">
18
19 <div class="col-lg-4 col-med-8 col-sm-8 text-primary" style="height: fit-content;">
20
21 <form action="{% url 'gallery_app:editgallery' user.username new_gallery.id %} " style="font-weight: bolder;" enctype='multipart/form-data' method='POST' class='gap-2'>
22
23 {% csrf_token %}
24
25
26 <div class="form-group mb-5">
27 <label style="margin-right: 20px;">Public Gallery</label>
28 {{form.public_gallery}}
29 </div>
30
31 <div class="form-group mb-5">
This is the line of code being highlighted as cause for error (form action):
<form action="{% url 'gallery_app:editgallery' user.username new_gallery.id %} " style="font-weight: bolder;" enctype='multipart/form-data' method='POST' class='gap-2'>
Views.py:
#login_required
def newgallery(request, username):
if request.method == 'GET':
form = NewGalleryForm
context = {
'form': form,
'username': username,
}
return render(request, 'galleries/newgallery.html', context)
def editgallery(request, username):
if request.method == "POST":
form = NewGalleryForm(request.POST)
if form.is_valid():
new_gallery = form.save(commit = False)
## connect the new gallery with the user (foreign key)
new_gallery.user = request.user
new_gallery.save()
url = "https://api.opensea.io/api/v1/assets?order_direction=desc&offset=0&limit=5"
params={'owner': new_gallery.wallett_address}
headers = {
"Accept": "application/json",
"X-API-KEY": ""
}
response = requests.request("GET", url, headers=headers, params=params)
response = response.json()["assets"]
list_of_nfts = []
for dictionary in response:
token_id = dictionary["token_id"]
token_address = dictionary["asset_contract"]["address"]
contract_address = 'https://api.opensea.io/api/v1/asset/' + token_address + '/' + token_id + '/'
name = dictionary["name"]
if len(name) > 50:
name = (name[:50] + '...')
nft_created_date = dictionary["asset_contract"]["created_date"]
nft_created_date = nft_created_date[:10]
nft_created_date = datetime.strptime(nft_created_date, '%Y-%m-%d').strftime('%m/%d/%Y')
image = dictionary["image_url"]
description = dictionary["description"]
if description is not None and '*' in description:
head, sep, tail = description.partition('*')
description = head
if description is not None and len(description) > 50:
description = (description[:150] + '...')
if isinstance(description, str) != True:
description = 'No description provided'
link = dictionary["permalink"]
nft_dict = {
'contract_address': contract_address,
'name': name,
'image': image,
'description': description,
'link': link,
'nft_created_date': nft_created_date,
}
list_of_nfts.append(nft_dict)
context = {
'new_gallery': new_gallery,
'list_of_nfts': list_of_nfts,
'raw_nft_data': json.dumps(list_of_nfts),
'new_gallery_name': new_gallery.gallery_name,
'user': new_gallery.user,
username:username,
}
return render(request, 'galleries/editgallery.html', context)
New Gallery HTML (page where user enters basic information regarding New Gallery that he or she is creating... when this form is submitted, the user is brought to a page where they can edit the gallery that was just created (by edit, I mean add new NFT's to that gallery):
<div class="row mb-3">
<div class="col-lg-12 col-sm-12 text-primary d-flex justify-content-center align-items-center">
<h1
class="homepagetitle mt-4 mb-5"
style="font-size: 2.4rem; color: rgb(231, 114, 208)"
>
Create new gallery
</h1>
</div>
</div>
<div class="row mb-3 d-flex justify-content-center">
<div class="col-lg-4 col-med-8 col-sm-8 text-primary" style="height: fit-content;">
<form action="{% url 'gallery_app:editgallery' user.username new_gallery.id %} " style="font-weight: bolder;" enctype='multipart/form-data' method='POST' class='gap-2'>
{% csrf_token %}
<div class="form-group mb-5">
<label style="margin-right: 20px;">Public Gallery</label>
{{form.public_gallery}}
</div>
<div class="form-group mb-5">
<label>Gallery Name </label>
{{form.gallery_name}}
</div>
<div class="form-group mb-5">
<label>Wallett Address</label>
<span class="hovertext" style="color: rgb(231, 114, 208); font-weight: normal;" data-hover="You will be adding NFT's from this wallet. Max wallet size: 50 NFT's">?</span>
{{form.wallett_address}}
</div>
<div class="form-group mb-5">
<label style="margin-right: 20px;">Category </label>
{{form.gallery_category}}
</div>
<button
type="submit"
class="btn btn-dark mt-4 mb-4"
style="
font-size: 1.1rem;
height: 50px;
width:fit-content;
"
>
Add NFT's &nbsp <i class="far fa-arrow-alt-circle-right"></i>
</button>
</form>
</div>
</div>
User Profile HTML (page where user clicks on an a tag to bring them to the the New Gallery HTML (the other HTML I have listed above). That is when the code breaks and gives that error. The url in that a tag is href="{% url 'gallery_app:newgallery' user.username %}":
<h1 class="homepagetitle mt-4 mb-5 d-flex justify-content-center align-items-center" style="font-size: 2.4rem; color: rgb(231, 114, 208);">
Hello&nbsp
<span style="font-size: 2.4rem; color: rgb(231, 114, 208);"
>{{user.username}}&nbsp<i class="far fa-hand-paper" style="font-size: 2.4rem; color: rgb(231, 114, 208);"></i></span
>
</h1>
{% endif %}
<div class="row col-12">
<div class="col-lg-6">
<div class="pt-3 profile-image">
<img
src="{% static user.avatar.url %}"
alt="{{user.username}}'s avatar"
class="rounded-circle shadow"
height="300"
width="275"
/>
</div>
{% if request.user == user %}
<span>
<div class="editicon">
<a
href="{% url 'users_app:update' user.username %}"
style="
color: rgb(226, 81, 197);
-webkit-text-stroke: 1px black;
text-decoration: none;
"
>
<i class="fas fa-user-edit"></i>
</a>
</div>
</span>
{% endif %}
<!-- 'users_app:update' user.username -->
<table class="table profile-margin">
<tbody>
{% if request.user == user %}
<tr>
<th scope="row"></th>
<td>Name:</td>
<td>{{user.first_name}} {{user.last_name}}</td>
</tr>
<tr>
<th scope="row"></th>
<td>Email:</td>
<td>{{user.email}}</td>
</tr>
{% endif %}
<tr>
<th scope="row"></th>
<td>Username:</td>
<td>{{user.username}}</td>
</tr>
<tr>
<th scope="row"></th>
<td>Profile created:</td>
<td>{{user.date_joined|date}}</td>
</tr>
<tr>
<th scope="row"></th>
<td>Galleries:</td>
<td>0</td>
</tr>
<tr>
<th scope="row"></th>
<td>Followers:</td>
<td>0</td>
</tr>
<tr>
<th scope="row"></th>
<td>Following:</td>
<td>0</td>
</tr>
</tbody>
</table>
</div>
<div class="col-lg-6">
{% if request.user.is_authenticated %}
<h3 class=" d-flex homepagetitle" style="justify-content:center; margin-top: 30px; margin-bottom: 0px; padding:10px; height: 75px; font-size: 2.2rem; color: rgb(231, 114, 208);">
<i><a class="homepagetitle far fa-plus-square" href="{% url 'gallery_app:newgallery' user.username %}" style="text-decoration: none; font-size: 2.2rem; color: rgb(231, 114, 208); position:relative; left: -70px; font-size: 2rem;"></i></a>
Your Galleries:
</h3>
{% else %}
<h3 class=" d-flex justify-content-center homepagetitle" style="margin-top: 30px; margin-bottom: 0px; padding:10px; height: 75px; font-size: 2.2rem; color: rgb(231, 114, 208);">
{{user.username}}'s Galleries:
</h3>
{% endif %}
<div class='user-galleries d-flex justify-content-center' style="background-color: rgb(247, 229, 243); border-radius: 8px;">
<div class="gallery-posts py-3">
<table class="table profile-margin" style="color:rgb(231, 114, 208); font-weight: bolder;">
<tbody>
{% for gallery in user.newgallery.all %}
<tr>
<th scope="row"></th>
<td>{{ gallery.gallery_name }}</td>
<td>NFT's: 0</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
Urls.py:
app_name = 'gallery_app'
urlpatterns = [
path('newgallery/<str:username>', views.newgallery, name='newgallery'),
path('editgallery/<str:username>/<int:gallery_id>', views.editgallery, name='editgallery'),
path('galleryview/<str:username>/<int:gallery_id>', views.galleryview, name='galleryview'),
]
It looks like the url argument new_gallery.id is empty when you render the html template.
update: so the template is called from view newgallery.
In your original code there is 2 things to change:
to instantiate the form please add () after NewGalleryForm. Without you just handover a link to the class.
in this view/template you do not yet have an instance of newgallery (just the form). So you can not use newgaller.id. Implement a POST branch in newgallery to save it and remove newgallery.id from the form action and point the action back to newgallery view.
after saving you have a newgallery instance with an id and you can call the edit view if you need to with newgallery in the context
def newgallery(request, username):
if request.method == 'POST':
# save newgallery here
if request.method == 'GET':
form = NewGalleryForm()
context = {
'form': form,
'username': username,
}
return render(request, 'galleries/newgallery.html', context)
<form action="{% url 'gallery_app:newgallery' user.username %} " style .... >
You need to pass the gallery as context into the view that has the edit form. I don't see in the views that you posted that you have a detail view but I do see a detail view url. So I'm assuming you're passing the edit form to your create view instead? That view doesn't return a context with new_gallery as a context variable. I would create a detail view for your gallery instead and pass the edit form, user and gallery as context to the template.
Reverse for 'editgallery' with arguments '('rodneyadmin', '')' not found.
New context
def galleryview(request, username, gallery_id):
# Logic
gallery = get_object_or_404(Gallery, pk=gallery_id)
context = {
'form': form,
'username': username,
'new_gallery': gallery,
}
# return an html response with context
Also, when you instantiate an unbound form you should add parenthesis after it.
form = NewGalleryForm()

Django Form POST problem in a Bootstrap Modal

I'm searching for this issue for days... And, unfortunately, couldn't find the answer.
I have a view (Buildings) and I want to add/edit a Building with a modal. With my current code, I can add new Building. However, because I can't pass the id (pk) of an existing Building, I can't update it.
I've two views: one for the table, other for the form. I noticed that, when I POST, my Building view posts, not the newBuilding view.
I tried to get pk from kwargs in newBuilding view, but I can't get it in the post method.
The only thing left is to update..
Let me share my code.
Thanks in advance!
urls.py
path('app/buildings/', login_required(views.Buildings.as_view()), name='buildings'),
path('app/buildings/<int:pk>', login_required(views.NewBuilding.as_view()), name='buildings-pk'),
models.py
class Buildings(TemplateView):
template_name = 'main_app/buildings.html'
model = models.Building
def get_context_data(self, **kwargs):
context = super(Buildings, self).get_context_data(**kwargs)
# Get selected site from cache
active_site = models.Site.objects.filter(id=self.request.session.get('active_site')).get()
context['active_site'] = active_site
filtered_buildings = models.Building.objects
context['buildings'] = filtered_buildings.all()
return context
def get_form_kwargs(self):
kwargs = super(Buildings, self).get_form_kwargs()
kwargs.update({'active_site': self.request.session.get('active_site'), 'edited_building_id': None})
return kwargs
def post(self, request, *args, **kwargs):
if request.method == 'POST':
NewBuilding.post(self, request=request, slug=None)
return HttpResponseRedirect(reverse_lazy('main_app:buildings'))
else:
print("error")
...
class NewBuilding(FormView):
template_name = 'main_app/new/new_building.html'
form_class = forms.NewBuildingForm
active_site = None
def get_context_data(self, **kwargs):
context = super(NewBuilding, self).get_context_data(**kwargs)
# Get selected site from cache
self.active_site = models.Site.objects.filter(id=self.request.session.get('active_site')).get()
context['active_site'] = self.active_site
context['edited_building_id'] = self.kwargs['pk']
return context
def get_form_kwargs(self):
kwargs = super(NewBuilding, self).get_form_kwargs()
kwargs.update({'active_site': self.request.session.get('active_site'),
'edited_building_id': self.kwargs['pk']})
return kwargs
def post(self, request, slug=None, *args, **kwargs):
if request.method == 'POST':
# HERE, I need to assign the building to be edited.
# if kwargs['edited_building_id']:
# new_building = models.Building.objects.get(id=self.kwargs['edited_building'])
# else:
new_building = models.Building()
new_building.site = models.Site.objects.filter(id=self.request.session.get('active_site')).get()
if new_building.name != request.POST.get('name'):
new_building.name = request.POST.get('name')
if new_building.address != request.POST.get('address'):
new_building.address = request.POST.get('address')
new_building.save()
else:
print("error")
buildings.html
<div class="portlet box blue">
<div class="portlet-title">
<div class="tools">
<a href="javascript:;" class="collapse">
</a>
</div>
</div>
<div class="portlet-body">
<div class="table-toolbar">
<div class="row">
<div class="col-md-12">
<div class="btn-group pull-right">
<button id="sample_editable_1_new" class="btn green" data-target="#full-width" data-toggle="modal" href="{% url "main_app:buildings-pk" pk=0%}">
Add New <i class="fa fa-plus"></i>
</button>
</div>
</div>
</div>
</div>
{# modal for new and edited entry#}
<div id="full-width" class="modal container fade" tabindex="-1">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true"></button>
<h4 class="modal-title">Add Building</h4>
</div>
<div class="modal-body">
{# modal body#}
</div>
</div>
<table class="table table-striped table-hover table-bordered" id="sample_editable_1">
<thead>
<tr>
<th class="text-center">
Name
</th>
<th class="text-center">
Address
</th>
<th class="text-center">
Type
</th>
<th class="text-center">
Edit
</th>
</tr>
</thead>
<tbody>
{% for building in buildings %}
<tr>
<td>
{{ building.name }}
</td>
<td>
{{ building.address }}
</td>
<td>
{{ building.type | default_if_none:"-" }}
</td>
<td>
<a class="edit" data-target="#full-width" data-toggle="modal" href="{% url "main_app:buildings-pk" pk=building.id%}">
Edit </a>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
new_building.html
<form class="form-horizontal" method="POST">
{% csrf_token %}
<div class="form-body">
<div class="form-group last">
<label class="col-md-3 control-label">Site</label>
<div class="col-md-4">
<span class="form-control-static">{{ active_site.name }}</span>
</div>
</div>
<div class="form-group">
<label class="col-md-3 control-label">Name</label>
<div class="col-md-4">
{{ form.name }}
</div>
</div>
<div class="modal-footer">
<button type="submit" class="btn blue">Submit</button>
<button type="button" class="btn default" data-dismiss="modal">Cancel</button>
</div>
</form>
forms.py
class NewBuildingForm(forms.ModelForm):
active_site = None
edited_building_id = 0
class Meta:
model = models.Building
fields = ["name", "address", "type", "site", "public_area",
"electricity_utility_meter", "water_utility_meter", "gas_utility_meter", "hot_water_utility_meter"]
def __init__(self, *args, **kwargs):
self.active_site = kwargs.pop('active_site')
self.edited_building_id = kwargs.pop('edited_building_id')
super(NewBuildingForm, self).__init__(*args, **kwargs)
edited_building = models.Building.objects.filter(id=self.edited_building_id)
self.fields['name'] = forms.CharField(
widget=forms.TextInput(attrs={'placeholder': 'Name', 'class': 'form-control input-circle'}))
self.fields['address'] = forms.CharField(
widget=forms.TextInput(attrs={'placeholder': 'Address', 'class': 'form-control input-circle'}),
required=False)
if edited_building:
self.fields['name'].initial = edited_building.get().name
self.fields['address'].initial = edited_building.get().address
I try to update kwargs on FormView (because I can get edited_building_id there), but I can't access kwargs on POST https://imgur.com/G7UcmLo

Django Multiple Files Upload

I would like to upload multiples files in my model in Django. I am struggling on the HTML part. I would like to include it part of my detail view without having to create a special view to upload the files. When I click on the button, it open the file upload, I select them but they don`t seem to be attached to the model. Any ideas please?
models.py
class Quote(models.Model):
name = models.CharField(max_length=30)
class Attachment(models.Model):
quote = models.ForeignKey(Quote, on_delete=models.CASCADE, blank=True, null=True)
name = models.CharField(max_length=30)
file = models.FileField(upload_to='quotes/%Y/%m/%d',blank=True, null=True)
def __str__(self):
return self.name
forms.py
class AttachmentForm(forms.ModelForm):
class Meta:
model = Attachment
fields = ('file', )
widgets = {
'file': ClearableFileInput(attrs={'multiple': True}),
}
# widget is important to upload multiple files
views.py
#login_required(login_url="/login/")
def add_attachment(request, quote_id):
form = AttachmentForm(request.POST or None, request.FILES or None)
quote = get_object_or_404(Quote, pk=quote_id)
if form.is_valid():
quotes_attachments = quote.attachment_set.all()
attachment = form.save(commit=False)
attachment.quote = quote
attachment.attachments = request.FILES['attachments']
file_type = attachment.attachments.url.split('.')[-1]
file_type = file_type.lower()
attachment.save()
return render(request, 'quotes/quote_detail.html', {'quote': quote})
context = {
'quote': quote,
'form': form,
}
return render(request, 'quotes/quote_detail.html', context)
quote_detail.html
<div class="card-block">
<form action="/static/assets/plugins/fileupload/js/file-upload.php" method="post" class="dropzone" enctype="multipart/form-data" >
<div class="fallback">
<input name="file" type="file" multiple
style="display: none;"
data-url="{% url 'projects:add_attachment' quote.id %}"
data-form-data='{"csrfmiddlewaretoken": "{{ csrf_token }}"}'>
</div>
</form>
<table id="table" class="table table-striped table-bordered table-hover">
<thead>
<tr>
<th>File Name</th>
<th>File</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
<tr>
<td>{{ quote.attachments.id }}</td>
<td></td>
<td><a target="_blank" href="{{ quote.attachments.url }}"><i class="fas fa-eye"></i></a></td>
</tr>
</tbody>
</table>
</div>
file-upload.php
<?php
$ds= DIRECTORY_SEPARATOR; //1
$storeFolder = 'uploads'; //2
if (!empty($_FILES)) {
$tempFile = $_FILES['file']['tmp_name']; //3
$targetPath = dirname( __FILE__ ) . $ds. $storeFolder . $ds; //4
$targetFile = $targetPath. $_FILES['file']['name']; //5
move_uploaded_file($tempFile,$targetFile); //6
}
?>

Generic detail view Index must be called with either an object pk or a slug in the URLconf

I am trying to have one form and one modelin one view which is working. But when I am trying to save the form I am getting the error message: Generic detail view Index must be called with either an object pk or a slug in the URLconf.
Here are my views nad urls:
class Index(generic.CreateView):
template_name='home.html'
form_class=DistributionForm
models=Lecturer
queryset = Lecturer.objects.all()
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context ['lecturer_list'] = Lecturer.objects.order_by('lecturer')
return context
def post(self, request, *args, **kwargs):
self.object = self.get_object()
form = self.get_form()
if form.is_valid():
return self.form_valid(form)
else:
return self.form_invalid(form)
urls.py
from django.urls import path
from . import views
from django.conf.urls.static import static
from django.conf import settings
from django.contrib.staticfiles.urls import staticfiles_urlpatterns
app_name='distribution'
urlpatterns=[
path('',views.Index.as_view(),name='home'),
path('hocalar/<slug:slug>/',views.LecturerDistribution.as_view(),name='lecturer_distribution'),
path('dersler/<slug:slug>/',views.LectureDistribution.as_view(),name='lecture_distribution'),
]
urlpatterns += staticfiles_urlpatterns()
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
EDIT
Here are my other two views
class LecturerDistribution(generic.DetailView):
model=Lecturer
template_name='lecturer.html'
def get_success_url(self):
return reverse('lecturer_distribution', kwargs={'slug': self.object.slug})
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context ['distribution'] = Distribution.objects.filter(lecturer=self.object).order_by('-created_on')
return context
class LectureDistribution(generic.DetailView):
model=Lecture
template_name='lecture.html'
def get_success_url(self):
return reverse('lecture_distribution', kwargs={'slug': self.object.slug})
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context ['distribution_'] = Distribution.objects.filter(lecture=self.object).order_by('-created_on')
return context
And here my Template
{% extends "base.html" %}
{%block content%}
{% load crispy_forms_tags %}
<div class="container">
<div class="form-group pull-right">
<input type="text" class="search form-control" placeholder="Ara">
</div>
<span class="counter pull-right"></span>
<table class="table table-hover results">
<thead>
<tr>
<th >Hoca</th>
<th >Ders</th>
</tr>
<tr class="warning no-result">
<td><i class="fa fa-warning"></i> Sonuç Yok</td>
</tr>
</thead>
<tbody>
{%for lec in lecturer_list%}
<tr>
<td>
<p ><a style="text-decoration:none" href="{% url 'distribution:lecturer_distribution' slug=lec.slug%}">{{lec.lecturer}}</a></p>
</td>
<td>
{%for ders in lec.lecture.all%}
<a style="text-decoration:none" href="{% url 'distribution:lecture_distribution' slug=ders.slug%}">{{ders.lecture}}</a>,
{% endfor%}
</td>
</tr>
{%endfor%}
</tbody>
</table>
</div>
<div class="col-md-2 float-right ">
<button style= "position: fixed; top:175px; " type="button" class="btn btn-primary" data-toggle="modal" data-target="#exampleModal" data-whatever="#mdo">Add New Distribution</button>
</div>
<div class="modal fade" id="exampleModal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLabel">New Distribution</h5>
</div>
<div class="modal-body">
<form method="post" style="margin-top: 1.3em;">
{% csrf_token %}
{{ form|crispy }}
<div class="modal-footer">
<button type="submit" class="btn btn-primary">Submit</button>
<button type="submit" class="btn btn-secondary" data-dismiss="modal">Close</button>
</div>
</form>
</div>
</div>
</div>
</div>
<style >
body{
padding:20px 20px;
}
.results tr[visible='false'],
.no-result{
display:none;
}
.results tr[visible='true']{
display:table-row;
}
.counter{
padding:8px;
color:#ccc;
}
</style>
<script>
$(document).ready(function() {
$(".search").keyup(function () {
var searchTerm = $(".search").val();
var listItem = $('.results tbody').children('tr');
var searchSplit = searchTerm.replace(/ /g, "'):containsi('")
$.extend($.expr[':'], {'containsi': function(elem, i, match, array){
return (elem.textContent || elem.innerText || '').toLowerCase().indexOf((match[3] || "").toLowerCase()) >= 0;
}
});
$(".results tbody tr").not(":containsi('" + searchSplit + "')").each(function(e){
$(this).attr('visible','false');
});
$(".results tbody tr:containsi('" + searchSplit + "')").each(function(e){
$(this).attr('visible','true');
});
var jobCount = $('.results tbody tr[visible="true"]').length;
if(jobCount == '0') {$('.no-result').show();}
else {$('.no-result').hide();}
});
});
</script>
{% endblock content%}
Thank You in Advance
Try adding a success_url to your CreateView to redirect you to the homepage
from django.core.urlresolvers import reverse_lazy
class Index(generic.CreateView):
template_name='home.html'
form_class=DistributionForm
models=Lecturer
queryset = Lecturer.objects.all()
success_url = reverse_lazy('home')
Otherwise it will redirect you to the model's get_absolute_url path
I think i found your problem, because you are using the get_object() in your post function in your index view.
see code:
def get_object(self, queryset=None):
"""
Return the object the view is displaying.
Require `self.queryset` and a `pk` or `slug` argument in the URLconf.
Subclasses can override this to return any object.
"""
# Use a custom queryset if provided; this is required for subclasses
# like DateDetailView
if queryset is None:
queryset = self.get_queryset()
# Next, try looking up by primary key.
pk = self.kwargs.get(self.pk_url_kwarg)
slug = self.kwargs.get(self.slug_url_kwarg)
if pk is not None:
queryset = queryset.filter(pk=pk)
# Next, try looking up by slug.
if slug is not None and (pk is None or self.query_pk_and_slug):
slug_field = self.get_slug_field()
queryset = queryset.filter(**{slug_field: slug})
# If none of those are defined, it's an error.
if pk is None and slug is None:
raise AttributeError(
"Generic detail view %s must be called with either an object "
"pk or a slug in the URLconf." % self.__class__.__name__
)
try:
# Get the single item from the filtered queryset
obj = queryset.get()
except queryset.model.DoesNotExist:
raise Http404(_("No %(verbose_name)s found matching the query") %
This is the code for get_object(), because you don't have a pk and no slug available. It returns the generic detail view error.
raise AttributeError(
"Generic detail view %s must be called with either an object "
"pk or a slug in the URLconf." % self.__class__.__name__
)
You can delete the def post in your index view because the form_valid() that your are using is already in the create view. You don't need it.

Django Class Based Views and Queries

I am attempting to filter for a single object, more specifically, today's entry. I then want to take that query and display the result within the template. No matter what I do I can't seem to get the filter to display anything in the template. I am not sure whether I need the query to be written within the view, the model, or both. My familiarity with Django querying is pretty light. A great resource on this topic would be extremely helpful as well.
I'm semi-new to Django, so any help you can provide would be much appreciated.
models.py
class Entry(models.Model):
date = models.DateField(blank=True, null=True,)
euros = models.CharField(max_length=500, blank=True, null=True)
comments = models.CharField(max_length=900, blank=True, null=True)
euros_sum = models.DecimalField(max_digits=6, decimal_places=2, blank=True, null=True)
xrate = models.DecimalField(max_digits=6, decimal_places=2, blank=True, null=True)
dollars_sum = models.DecimalField(max_digits=6, decimal_places=2, blank=True, null=True)
daily_savings_dollars = models.DecimalField(max_digits=6, decimal_places=2, blank=True, null=True)
def get_absolute_url(self):
return reverse('argent:detail', kwargs={'pk': self.pk})
views.py:
class IndexView(generic.ListView):
template_name = 'argent/index.html'
context_object_name = 'object_list'
queryset = Entry.objects.all()
filter = Entry.objects.filter(date=today_date)
print(filter)
class DetailView(generic.DetailView):
model = Entry
template_name = 'argent/detail.html'
class EntryCreate(CreateView):
form_class = EntryForm
template_name = 'argent/entry_form.html'
def form_valid(self, form):
return super(EntryCreate, self).form_valid(form)
class EntryUpdate(UpdateView):
model = Entry
form_class = EntryForm
template_name = 'argent/entry_form.html'
def form_valid(self, form):
return super(EntryUpdate, self).form_valid(form)
Note1: When I print "filter =" I get the correct object returned in the console.
Note2: I am using my "queryset =" further down my template and it works
perfectly fine.
template(index.html):
<div class="container" style="font-family: 'Dosis', serif;">
<div class="jumbotron" style="background: #ebebeb">
{% for Entry in filter %}
<h1>Today's Spending</h1>
<div class="container container-fluid" style="margin-left: 30px; margin-right: 30px; font-family: 'Dosis', serif; color: white;">
<div class="container container-fluid">
<table class="table">
<thead>
<tr>
<th colspan="2" style="font-size: large; color: #337ab7; font-weight: bold">{{ first.date }}</th>
</tr>
</thead>
<tbody>
<tr>
<td align="left" style="color: #337ab7; font-weight: bold">Receipts:</td>
<td style="color: #FF6F18;"> {{ first.euros }} </td>
</tr>
<tr>
<td align="left" style="color: #337ab7; font-weight: bold">Total Euros Spent:</td>
<td style="color: #FF6F18;">€{{first.euros_sum}}</td>
</tr>
<tr>
<td align="left" style="color: #337ab7; font-weight: bold">Total Dollars Spent:</td>
<td style="color: #FF6F18;">${{first.dollars_sum}}</td>
</tr>
<tr>
<td align="left" style="color: #337ab7; font-weight: bold">Exchange Rate:</td>
<td style="color: #FF6F18;">{{ first.xrate }}</td>
</tr>
<tr>
<td align="left" style="color: #337ab7; font-weight: bold">Daily Savings:</td>
<td style="color: #FF6F18;">
{% if last.daily_savings_dollars > 0 %}
<div class="NegativeSavings" style="font-weight: bold">-
{% else %}
<div class="PositiveSavings" style="font-weight: bold">+
${{ first.daily_savings_dollars }}
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
{% endfor %}
<div class="container container-fluid" style="font-family:'Dosis', serif">
<!-- Entry List -->
<div class="row" style="margin-left: 20px; margin-right: 20px">
<div>
&nbsp
</div>
{% if object_list %}
{% for Entry in object_list %}
<div class="col-sm-4 col-lg-3">
<div class="thumbnail" style="background: #ebebeb"; >
<a href="{% url 'argent:detail' Entry.id %}">
<h3 align="center" style="font-weight: bold">{{ Entry.date }}</h3>
</a>
<div class="caption">
<h4 align="center" style="color: #FF6F18">€{{ Entry.euros_sum }}
<!-- View Details -->
<a href="{% url 'argent:detail' Entry.id %}"><button type="button" class="btn btn-link btn-lg">
<span class="glyphicon glyphicon-info-sign" aria-hidden="true"></span>
</button></a>
<!-- Update -->
<a href="{% url 'argent:entry-update' Entry.id %}"><button type="button" class="btn btn-link btn-lg" style="padding: 0%">
<span class="glyphicon glyphicon-pencil" aria-hidden="true"></span>
</button></a></h4>
</div>
</div>
</div>
{% endfor %}
{% endif %}
</div>
</div>
Thanks in advance for your help!
You shouldn't do any db interaction at module level. You should override get_queryset (for what will be passed as object_list to the template) and get_context_data if you want additional stuff in your template context like the filtered queryset:
from django.utils import timezone
class IndexView(generic.ListView):
template_name = 'argent/index.html'
context_object_name = 'object_list'
def get_queryset(self):
return Entry.objects.all()
def get_context_data(self, **kwargs):
ctx = super(IndexView, self).get_context_data(**kwargs)
ctx['filter'] = Entry.objects.filter(date=timezone.datetime.today())
return ctx
The django documentation in general and its ListView section in particular are a good starting point. The django tutorial is worth completing, as well.
Modify your view to pass one of the querysets in as a context.
class IndexView(generic.ListView):
template_name = 'argent/index.html'
context_object_name = 'object_list'
#queryset = Entry.objects.all() use the get_queryset method to get this
#filter = Entry.objects.filter(date=today_date) add this using the get_context_data method
def get_context_data(self, **kwargs):
context = super(IndexView, self).get_context_data(**kwargs)
context.update({
'filter': Entry.objects.filter(date=today_date),
})
return context
def get_queryset(self):
return Entry.objects.all()

Categories