form_valid updateview - django-models

Good day dear Community!
my Model:
class CheckList(models.Model):
author = models.ForeignKey(User, null=True, on_delete=models.SET_NULL)
...
datecompleted = models.DateTimeField(null=True)
post_date = models.DateTimeField(auto_now=True)
form.py:
class CompletionChecklistForm(forms.ModelForm):
class Meta:
model = CheckList
fields = ('vessels_name', 'datecompleted')
now I'd like to update 'datecompleted' field:
views.py:
class CompleteItemView(UpdateView):
model = CheckList
form_class = CompletionChecklistForm
template_name = 'completion_checklist.html'
success_url = reverse_lazy('home')
def form_valid(self, form):
form.instance.datecompleted = timezone.now()
form.instance.save()
return super(CompleteItemView, self).form_valid(form)
Template:
{% block content %}
<h2 class="d-flex justify-content-center">Completion of current Checklist</h2>
<br>
<br>
<container class="d-flex justify-content-center">
<div class="form-group w-50">
<h4>Complete: {{ object.vessels_name }}?</h4><br>
{{ object.datecompleted }}
<form method="post">
{% csrf_token %}
<div class="clearfix">
<button class="btn btn-danger float-left" type="submit">Yes</button>
No, back
</div>
</form>
</div>
</container>
{% endblock %}
There is no error message but and field value doesn't change as well.
Am I right with my View?
Thank you in advance.

Related

Pagination for the objects returned in 'else' clause

I have following model, where pagination works ok only if I don't filter by tags. As soon as I filter ads by tags, pagination doesn't work.
class AdListView(ListView):
paginate_by = 2
model = Ad
context_object_name = 'ads'
def get_context_data(self, **kwargs):
if self.request.GET.get('tags') is None:
context = super().get_context_data(**kwargs)
context.update(tags=Tag.objects.all())
return context
else:
tag_submitted = Tag.objects.get(name=self.request.GET.get('tags'))
ads_by_tag = tag_submitted.related_ads.all()
context = {
'ads': ads_by_tag
}
context.update(tags=Tag.objects.all())
return context
What needs to be done so that pagination works for both cases, with and without filter?
below are models.py and template
models.py
class Tag(BaseModel):
def __str__(self):
return str(self.name)
class Ad(BaseModel):
name = models.CharField(max_length=100)
description = models.TextField(max_length=500)
category = models.ForeignKey(Category, on_delete=models.CASCADE)
seller = models.ForeignKey(Seller, on_delete=models.CASCADE)
date_created = models.DateField(auto_now_add=True)
date_modified = models.DateField(auto_now=True)
tags = models.ManyToManyField(Tag, related_name='related_ads')
price = models.PositiveIntegerField(default=0)
archived = models.BooleanField(default=False)
def __str__(self):
return str(self.name)
class Meta:
ordering = ['-date_created']
template
{% block content %}
<div class="container">
<div class="row">
<div class="w-75">
<table class="table">
<thead>
<tr>
<th scope="col">#</th>
<th scope="col">Title</th>
</tr>
</thead>
<tbody>
{% for ad in ads %}
<tr>
<td>{{ forloop.counter }}</td>
<td> {{ ad.name }} </td>
</tr>
{% empty %}
<li>No ads yet.</li>
{% endfor %}
</tbody>
</table>
</div>
<div class="w-25">
<table class="table">
<thead>
<tr>
<th scope="col">Tags</th>
</tr>
</thead>
<tbody>
{% for tag in tags %}
<tr>
<td> {{ tag }} </td>
</tr>
{% empty %}
<li>No tags yet.</li>
{% endfor %}
</tbody>
</table>
</div>
</div>
<div class="row">
<div class="pagination">
<span class="step-links">
{% if page_obj.has_previous %}
« first
previous
{% endif %}
<span class="current">
Page {{ page_obj.number }} of {{ page_obj.paginator.num_pages }}.
</span>
{% if page_obj.has_next %}
next
last »
{% endif %}
</span>
</div>
</div>
</div>
{% endblock %}
so this is a project to learn django, so any other comments on how to improve the code also welcome.
You should not filter in the .get_context_data() [Django-doc]. In Django you pass the (possibly) filtered queryset in .get_queryset(…) [Django-doc]. Django will then paginate the queryset, and add it to the context. By overriding the item in the context, you now have removed the paginated queryset, and added a filtered queryset instead.
You thus provide the filtered queryset, and let Django do the proper pagination:
class AdListView(ListView):
paginate_by = 2
model = Ad
context_object_name = 'ads'
def get_search_querystring(self):
copy = self.request.GET.copy()
copy.pop(self.page_kwarg, None)
return copy.urlencode()
def get_queryset(self, *args, **kwargs):
qs = super().get_queryset(*args, **kwargs)
if 'tags' in self.request.GET:
return qs.filter(tags__name=self.request.GET['tags'])
return qs
def get_context_data(*args, **kwargs):
return super().get_context_data(*args, tags=Tag.objects.all(), **kwargs)
Another problem is the link in the template: by using ?page={{ page_obj.next_page_number }}, this will "drop" the query string [wiki] that contains the search query, and only use page as the only variable in the query string.
In the template we thus can use the URL as:
<a href="?page={{ page_obj.next_page_number }}&{{ view.get_search_queryset|safe }}">
the same should happen with the other pagination links.

How I can show the models fields in my template

I am trying to extract the data from a model and show it to a template, but the data are not showing. Any help will be appreciated.
Here is the model:
class Schedule(models.Model):
team1 = models.CharField(max_length=50)
team1_pic = models.ImageField()
team2 = models.CharField(max_length=50)
team2_pic = models.ImageField()
timestamp = models.TimeField(default="", blank=True, null=True)
datestamp = models.DateField(default="", blank=True, null=True)
location = models.CharField(max_length=200)
Here is the view:
def schedule(request):
schedule = Schedule.objects.all()
context = {
'schedule': schedule
}
return render(request, 'schedule.html')
And finally the template:
<!-- Schedule Section Begin -->
<section class="schedule-section spad">
<div class="container">
<div class="row">
<div class="col-lg-8 left-blog-pad">
<div class="schedule-text">
<h4 class="st-title">World Cup 2019</h4>
<div class="st-table">
{% for sch in schedule %}
<table>
<tbody>
<tr>
<td class="left-team">
<img src="{% static 'img/schedule/flag-1.jpg' %}" alt="">
<h4>{{ sch.team1 }}</h4>
</td>
<td class="st-option">
<div class="so-text">{{ sch.location }}</div>
<h4>VS</h4>
<div class="so-text">{{ sch.date }}</div>
</td>
<td class="right-team">
<img src="{% static 'img/schedule/flag-2.jpg' %}" alt="">
<h4>{{ sch.team1 }}</h4>
</td>
</tr>
</tbody>
</table>
</div>
{% endfor %}
</div>
</div>
You need to pass context too.
def schedule(request):
schedule = Schedule.objects.all()
context = {
'schedule': schedule
}
return render(request, 'schedule.html',context)

How two dependent model can possibly join together in django-model thus I can extract all the data from these two models?

I am writing one blog site for my project group. At one stage I am now stacked and none of the solutions, available over open sources in youtube and also in stackoverfolow, has solved my problem. I know this is simple but as I am not very efficient in using django framework model system so I could not solve it.
I have 4 models linked with ForeignKey. Among those 4 models two of them I want to use for detailed_view. I am not able to populate data out of both models.
One model name "Term_t" as follows:
class Term_t(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL, default=1, on_delete=models.CASCADE)
preferred_term = models.CharField(max_length=120)
slug = models.SlugField(unique=True)
definition = models.TextField()
agrovoc_id = models.TextField()
uri = models.TextField()
translation_de = models.TextField()
broader_concept= models.CharField(max_length=120)
states = models.ForeignKey(TermState_t, default=1, on_delete=models.CASCADE)
categories = models.ForeignKey(Category_t, default=1, on_delete=models.CASCADE)
date_created = models.DateTimeField(auto_now_add=True)
updated_on = models.DateTimeField(auto_now=True)
def __unicode__(self):
return self.preferred_term
def __str__(self):
return self.preferred_term
class Meta:
ordering = ['-date_created']
## The other model is :
class AlternateTerm_t(models.Model):
alternate_terms = models.CharField(max_length=120)
pref_term = models.ForeignKey('Term_t', default=1, on_delete=models.CASCADE)
def __str__(self):
return self.alternate_terms
#My views.py is :
from django.shortcuts import render
from .models import Term_t, AlternateTerm_t
from itertools import chain
# Create your views here.
#from django.views import generic
#class TermList(generic.ListView):
#queryset = Term_t.objects.all().order_by("-date_created")
#template_name = 'index.html'
#class TermDetail(generic.DetailView):
#model = Term_t
#template_name = 'term_detail.html'
######################################
def term_list(request):
terms = Term_t.objects.all()
context = {
'term_list': terms
}
return render(request,"index.html", context)
def term_detail(request, slug):
term = Term_t.objects.filter(alternateterm_t__pref_term= 'term_t__preferred_term').values('user','preferred_term','alternateterm_t__alternate_terms','definition','agrovoc_id','uri','translation_de','broader_concept','date_created').get(slug=slug)
context={
'term':term,
}
return render(request, "term_detail.html", context)
user = models.ForeignKey(settings.AUTH_USER_MODEL, default=1, on_delete=models.CASCADE)
preferred_term = models.CharField(max_length=120)
slug = models.SlugField(unique=True)
definition = models.TextField()
agrovoc_id = models.TextField()
uri = models.TextField()
translation_de = models.TextField()
broader_concept= models.CharField(max_length=120)
states = models.ForeignKey(TermState_t, default=1, on_delete=models.CASCADE)
categories = models.ForeignKey(Category_t, default=1, on_delete=models.CASCADE)
date_created = models.DateTimeField(auto_now_add=True)
updated_on = models.DateTimeField(auto_now=True)
My term_detail.html is :
{% extends "base.html" %}
{% block content %}
<style>
.row > .property-label {
float: left;
padding-top: 10px;
padding-bottom: 10px;
padding-left: 15px;
padding-right: 15px;
position: relative;
width: 225px;
}
.row > .property-value-column {
display: inline-block;
width: calc(100% - 225px);
padding-top: 10px;
padding-bottom: 10px;
position: relative;
}
.row > .property_under{
border-bottom: 2px solid #34b1eb;}
body {
font-family: "Helvetica Neue",Helvetica,Arial,sans-serif;
font-size: 14px;
line-height: 1.42857143;
color: #333;
}
.break{
height: 10px;
}
.property-label > .property-click {
border-bottom: 2px dotted #CFCFCF;
}
</style>
<div class="container">
<div class="row">
<div class="col-md-8 card mb-4 mt-3 left top">
<div class="card-body">
<div class="row">
<div class="property-label">
<span class="property-click">PREFERRED TERM</span>
</div>
<div class="property-value-column">
<h1>{% block title %} {{ term.preferred_term }} {% endblock title %}</h1>
</div>
</div>
<div class="row">
<div class="property-label">
<span></span>
</div>
<div class="property-value-column property_under">
<p class=" text-muted">{{ term.user }} | {{ term.date_created }}</p>
</div>
</div>
<div class="row">
<div class="property-label">
<span class="property-click">ALTERNATE TERMS</span>
</div>
<div class="property-value-column property_under">
<p class="card-text ">{{ term.alternate_terms }}</p>
</div>
</div>
<div class="row">
<div class="property-label">
<span class="property-click">DEFINITION</span>
</div>
<div class="property-value-column property_under">
<p class="card-text ">{{ term.definition | safe }}</p>
</div>
</div>
<div class="break"></div>
<div class="row">
<div class="property-label">
<span class="property-click">BROADER CONCEPT</span>
</div>
<div class="property-value-column property_under">
<p class="card-text ">{{ term.broader_concept}}</p>
</div>
</div>
<div class="break"></div>
<div class="row">
<div class="property-label">
<span class="property-click">AGROVOC ID</span>
</div>
<div class="property-value-column property_under">
<p class="card-text ">{{ term.agrovoc_id }}</p>
</div>
</div>
<div class="break"></div>
<div class="row">
<div class="property-label">
<span class="property-click">URI</span>
</div>
<div class="property-value-column property_under">
<p class="card-text ">{{ term.uri }}</p>
</div>
</div>
<div class="break"></div>
<div class="row">
<div class="property-label">
<span class="property-click">DEFINITION (DE)</span>
</div>
<div class="property-value-column property_under">
<p class="card-text ">{{ term.translation_de | safe }}</p>
</div>
</div>
</div>
</div>
{% block sidebar %} {% include 'sidebar.html' %} {% endblock sidebar %}
</div>
</div>
{% endblock %}
#
I have got some erros like as follows:
ValueError at /soil-upper-texture-modification/
invalid literal for int() with base 10: 'term_t__preferred_term'
Request Method: GET
Request URL: http://127.0.0.1:8000/soil-upper-texture-modification/
Django Version: 2.1.4
Exception Type: ValueError
Exception Value:
invalid literal for int() with base 10: 'term_t__preferred_term'
Exception Location: D:\agrovoc_tool\venv\lib\site-packages\django\db\models\fields\__init__.py in get_prep_value, line 965
Python Executable: D:\agrovoc_tool\venv\Scripts\python.exe
Python Version: 3.6.6
Python Path:
['D:\\agrovoc_tool\\src',
'C:\\Program Files\\Hexagon\\ERDAS IMAGINE '
'2015\\usr\\lib\\Win32Release\\python',
'D:\\agrovoc_tool\\venv\\Scripts\\python36.zip',
'C:\\Users\\zoarder\\AppData\\Local\\Programs\\Python\\Python36\\DLLs',
'C:\\Users\\zoarder\\AppData\\Local\\Programs\\Python\\Python36\\lib',
'C:\\Users\\zoarder\\AppData\\Local\\Programs\\Python\\Python36',
'D:\\agrovoc_tool\\venv',
'D:\\agrovoc_tool\\venv\\lib\\site-packages',
'D:\\agrovoc_tool\\venv\\lib\\site-packages\\setuptools-39.1.0-py3.6.egg',
'D:\\agrovoc_tool\\venv\\lib\\site-packages\\pip-10.0.1-py3.6.egg']
Server time: Fri, 18 Oct 2019 10:34:20 +0000
I want to get the alternate_terms in my detailed_view , the particular place has marked in the following image: (there could have been one and more alternate_terms for one preferred term, so all the alternate terms will be inserted one after another by (,)
Output of detailed view
Please help me out of this problem.
Kind regards
Zoarder
I have solved my problem by a little change in views.py and detail.html:
def term_detail(request, id):
id=id
term = Term_t.objects.filter(id=id)
my_term = AlternateTerm_t.objects.filter(pref_term= id)
context={
'term':term,
'my_term':my_term,
}
return render(request, "term_detail.html", context)
HTML page edit:
<div class="row">
<div class="property-label">
<span class="property-click">ALTERNATE TERM</span>
</div>
<div class="property-value-column property_under">
<p class="card-text ">{%for r in my_term %}{{r.alternate_terms}}{% if not forloop.last %}, {% endif %}{% endfor %}</p>
</div>
</div>
OUTPUT:
enter image description here

add jquery counterup plugin to symfony 2 with assetic

I'm trying to add a counter up effect to my home page in a symfony 2 application with angular . i have added dependencies in my config.yml file like this :
counter:
inputs:
- "bundles/ubidelectricity/js/custom/waypoints.min.js"
- "bundles/ubidelectricity/js/custom/jquery.counterup.min.js"
and i have called counter in my twig like this :
{% block javascripts %}
{% javascripts
'#jquery'
'#bootstrap_4_js'
'#jqueryui'
'#elfinder'
'#fastclick'
'#angular'
'#angular_storage'
'#angular_table'
'#angular_translate'
'#angular_scroll'
'#angular_file_uplaod'
'#angular_dynamic_locale'
'#bootstrap_colorpicker'
'#videogular'
'#oclazyload'
'#breadcrumb'
'#ui_bootstrap'
'#loading_bar'
'#color_picker'
'#locationpicker'
'#multirange_slider'
'#site_front_scripts'
'#continuous_net_services'
'#continuous_net_directives'
'#site_front_controller' %}<script src="{{ asset_url }}"></script>
{% endjavascripts %}
{% endblock %}
and i have added html in the front page like this :
<div class="row pt-5 pb-5">
<div class="col-md-3 text-center">
<span class="counter">3300</span> <span class="counters">+</span>
<span class="counter-text">Buyers Organisations</span>
</div>
<div class="col-md-3 text-center">
<span class="counter">585</span>
<span class="counter-text">Buyer Partners</span>
</div>
<div class="col-md-3 text-center">
<span class="counter">41000</span> <span class="counters">+</span>
<span class="counter-text">Tenders / Quotes </span>
<span class="counter-text"> Every Year </span>
</div>
<div class="col-md-3 text-center">
<span class="counter">658</span>
<span class="counter-text">Industry Categories</span>
</div>
</div>
I use :
php app/console assets:install
php app/console assetic:dump
php app/console assetic:watch
but it doesn't work and there are no animations.

AngularJS and ModelForm: Submit button not working

The page is supposed to display the contents of the database in a table, with a "New" button to add a new entry to the db. When the user clicks the "New" button, a form appears below. It is a ModelForm for the user to input a new entry to the Model, and then submit via a "Submit" button below. This was working as expected, until I added in an AngularJS controller to handle the button click of "New". The problem is my "Submit" button does not work. I want it to submit the data to the ModelForm, but it appears to do nothing.
Here is my template:
{% extends "base.html" %}
{% block content %}
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<div class="container-fluid">
<div class="row">
<div class="col-sm-10 col-sm-offset-1">
<h2>Ratings</h2>
<table class="table table-bordered">
<thead>
<tr>
<th>Beer Name</th>
<th>Beer Rating</th>
<th>Notes</th>
<th>Brewer</th>
</tr>
</thead>
<tbody>
{% for rating in ratings %}
<tr>
<td>{{ rating.beer_name }}</td>
<td>{{ rating.score }}</td>
<td>{{ rating.notes }}</td>
<td>{{ rating.brewer }}</td>
<td>Edit</td>
<td><a class="btn btn-primary" href="{% url 'rating-delete' rating.id %}" value="{{ rating.id }}" name="delete" >Delete</a></td>
</tr>
{% endfor %}
</tbody>
</table>
<div ng-app="myApp" ng-controller="myCtrl">
<a ng-model="buttonClick" ng-click="is_clicked()" class="btn btn-primary">New</a>
<div ng-show="buttonClick" ng-cloak>
<div class="container-fluid">
<div class="row">
<div class="col-sm-10 col-sm-offset-1">
<h2>Enter a new rating</h2>
<form role="form" method="post">
{% csrf_token %}
<p>Beer Name: <input type="text" ng-model="myForm.beer_name"></input></p>
<p>Score: <input type="number" step="0.1" ng-model="myForm.score"></input></p>
<p>Notes: <input type="text" ng-model="myForm.notes"></input></p>
<p>Brewer: <input type="text" ng-model="myForm.brewer"></input></p>
<p><button ng-click="submit_to_form(myForm)" type="submit" class="btn btn-primary">Submit</button></p>
</form>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<script>
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope, $http){
$scope.myForm = {beer_name:'beer_name', score:'score', notes:'notes', brewer:'brewer'};
$scope.buttonClick = false;
$scope.is_clicked = function() {
$scope.buttonClick=true;
console.log($scope.buttonClick)
}
$scope.submit_to_form = function(data) {
$http.post('rating-home', data);
}
})
</script>
{% endblock %}
And urls.py:
from django.conf.urls import url
from django.contrib import admin
from ratings.views import home, RatingCreate, delete, edit
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^$', RatingCreate.as_view(), name='rating-home'),
url(r'rating/add/$', RatingCreate.as_view(), name='rating-add'),
url(r'rating/delete/(?P<row_id>[0-9]+)/$', delete , name='rating-delete'),
url(r'rating/edit/(?P<row_id>[0-9]+)/$', edit , name='rating-edit'),
]
And views.py for the Submit button:
class RatingCreate(View):
""" Create a new Rating """
form_class = RatingForm
template_name = 'home.html'
def get(self, request):
form = self.form_class()
context = {'ratings': Rating.objects.all(), 'form': form}
#return render(request, 'home.html', context)
return render(request, self.template_name, context)
def post(self, request):
form = self.form_class(request.POST)
if form.is_valid():
_ = form.save()
return redirect('rating-home')
return render(request, self.template_name, {'form: form'})
You should handle submitting the form with angular
<form ng-submit="myFunc(myData)">
<input type="text" ng-model="myData.name">
<input type="text" ng-model="myData.phone">
<button type="submit">Submit</button>
</form>
OR
<form >
<input type="text" ng-model="myData.name">
<input type="text" ng-model="myData.phone">
<button ng-click="myFunc(myData)">Submit</button>
</form>
and your controller:
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope){
$scope.myData= {name:'' , phone:''};
$scope.myFunc = function(data) {
console.log(data);
// data(myData array) can be send with angular $http.post() method
// e.g. : $http.post('/myUrl/', data)
}
})
Update:
Here is a good tutorial for angular $http service!

Resources