Django SQLite UPDATE - python

I am developing a webapp using django. Generally, I want to keep track of how much time a user has devoted to a project. So when the user starts working, I am registering a "Change" object in the database with the user, the project, and what time he start working. Now, how can I get the same "Change" object to a different view to log the end time? In my best attempt I got an "IntegrityError NOT NULL constraint failed". Here is the code:
views.py
#login_required
def main(request):
context = RequestContext(request)
user=request.user
if request.method=='POST':
projectid=request.POST['project']
project = Project.objects.get(pk=int(projectid))
if project:
change=Change(user=user, project=project,starttime=datetime.now())
change.save()
#return HttpResponse("I \'ve already start counting... You \'ve wasted 5 seconds already. Just joking. I don\'t know how to count...")
return render_to_response('ProjectLogging/timer.html', {'change':change}, context_instance=RequestContext(request))
else:
HttpResponse("Choose a valid project!")
else:
HttpResponse("Choose a POST method (???????)")
#login_required
def timer(request, change):
user=request.user
# schange=request.change
if request.method=='POST':
change=Change(endtime=datetime.now())
change.save()
return render_to_response('ProjectLogging/main.html',{'user':user, 'project_list':Project.objects.all()}, context_instance=RequestContext(request))
else:
return HttpResponse("Something went wrong with timer view.")
urls.py
urlpatterns=patterns('ProjectLogging',
url(r'^$', 'views.login', name="index"),
url(r'^login/$', 'views.login', name="login"),
url(r'^logout/$', 'views.logout', name="logout"),
url(r'^main/$','views.main', name="main"),
url(r'^timer/$', 'views.timer', {'change':'change'}),
)
and the Change model
class Change(models.Model):
user=models.ForeignKey(User)
project=models.ForeignKey('Project')
starttime=models.DateTimeField(null=True,blank=True)
endtime=models.DateTimeField(null=True, blank=True)
flagged=models.BooleanField(default=False, db_index=True)
def __repr__(self):
return ('Change in project %r from %r' % (self.project.title, self.user.username))
def __unicode__(self):
return ('%r in project: %r' % (self.user.get_full_name(), self.project.title))
def user_changes(self, user):
return self.filter(user==user)
Sorry for the primitive code. I m new to both Django and Python.

the error is here:
change=Change(endtime=datetime.now())
change.save()
You are trying to create a new object...
Instead you need to get the previous created one and save it.
you need to pass the id to the post , get the object and save it again:
change = Change.objects.get(id=change_id)
change.endtime=datetime.now()
change.save()
This is what I would do:
change the url from this
url(r'^timer/$', 'views.timer', {'change':'change'}),
to this:
url(r'^timer/$', 'views.timer', name='timer'),
Pass the change_id in the form as a hidden input. Since you're not using django Forms, you'll have to write this
<input type="hidden" value="{{ change.id }}" name="change_id" />
Change the timer function to this:
#login_required
def timer(request):
...
if request.method=='POST':
try:
change = Change.objects.get(id=request.POST.get('change_id'))
change.endtime=datetime.now()
change.save()
except:
...
that should be ok

Related

How to resolve Profile matching query doesnot exist error in django

I am new to Django framework. This problem "profile matching query does not exist" comes and I don't understand where this problem is generating from. Please Let me know what else code is needed to resolve this error. I will update this question.
profile matching query does not exist
!["profile matching query does not exist"](https://i.stack.imgur.com/YfHio.png)
I have rechecked the code in urls.py, views.py, index file. But I could not resolve this.
urls.py
from django.urls import path
from . import views
urlpatterns = [
path('',views.index, name = 'index'),
path('signup',views.signup, name = 'signup'),
path('signin',views.signin, name = 'signin'),
path('logout',views.logout, name = 'logout'),
path('settings',views.settings, name = 'settings'),
path('upload',views.upload, name = 'upload'),
]
views.py -> index
#login_required(login_url='signin')
def index(request):
user_object = User.objects.get(username=request.user.username)
user_profile = Profile.objects.get(user=user_object)
return render(request, 'index.html', {'user_profile':user_profile})
OK, so, it looks as though you don't have a Profile record associated with the User object.
def index(request):
user_object = User.objects.get(username=request.user.username)
user_profile = Profile.objects.get(user=user_object)
You need to check the value of user_object before looking for the profile, though pretty sure this is OK, then handle that Profile.objects.get if it doesn't actually find an associated Profile record.
You could do this by
try:
user_profile = Profile.objects.get(user=user_object)
except Profile.DoesNotExist:
... handle the error here
Alternatively, you could use the get_object_or_404 method, which would redirect you to your 404 page if it didn't find a record.
https://docs.djangoproject.com/en/4.1/topics/http/shortcuts/#get-object-or-404

Handling 2 Django forms - passing data from one to the other

I have 2 Django forms: one, where the user uploads an article, and the second, where the user can edit a list of article words into one of three buckets (change the column value: bucket 1-3).
forms.py
class UploadForm(forms.ModelForm):
class Meta:
model = Upload
fields = ('name','last_name','docfile',)
class Doc_wordsForm(forms.ModelForm):
class Meta:
model= Doc_words
fields= ('id','word','word_type','upload',) #upload is foreign key value
After the user uploads the article, I have a function in views.py that breaks down the uploaded article into a list of words.
I want these words to be looped through and added to a database table(where each row is a word), then have the second form reference these words.
Views.py
# upload_id = (request.GET.get("id"))
if request.method == 'POST':
form = UploadForm(request.POST, request.FILES)
if form.is_valid():
form.save()
data = request.FILES['docfile']#.read().decode('UTF-8')
words=get_keywords(data)
results=list(find_skills(words))
for word in results:
form2 = Resume_words(word = word, word_type='exclude', upload = upload_id)
form2.save()
return render(request, 'word_list.html',{
"results":results
})
else:
form = UploadForm()
return render(request, 'upload.html', {
'form':form
})
I having trouble pulling these pieces together and I'm desperate for help of any kind! I having trouble with the following steps:
I don't know how to capture the current users instance when saving to the table. I get an error in the above Views.py code.
I don't know how to have the second form reference the current user from the first form.
Please let me know if I can provide more information or clarity on anything above. Also, feel free to answer one question, or simply point me to where there is an example similar to this, any light shed is greatly appreciated.
There are many ways to get user's info in view. the most basic way (not recommended, AT ALL!) is to pass user's id to every view from every view. for example in login view you pass user's id in context:
return render(request, 'main_page.html',{
"user_id":user.id
})
and make every view get this id whether in url or query parameter.
using url:
urls.py
path('any/pk/', AnyView.as_view(), name='carrot'),
view.py
class AnyView(Views):
def get(request, pk):
user=User.objects.get(pk=pk)
def post(request, pk):
user=User.objects.get(pk=pk)
your_template.html
<!-- post request -->
<form action="{% url 'carrot' user_id %}" method="post">...</form>
<!-- get request -->
<a href={% url 'carrot' user_id %}></a>
using query parameters:
urls.py
path('any/', AnyView.as_view(), name='carrot'),
view.py
class AnyView(Views):
def get(request):
user=request.GET.get('pk', False)
if user:
user=User.objects.get(pk=pk)
def post(request):
user=request.POST.get('pk', False)
if user:
user=User.objects.get(pk=pk)
your_template.html
<!-- post request -->
<form action="{% url 'carrot' %}?pk={{ user_id }}" method="post">...</form>
<!-- get request -->
a much much better way is using django default authentication for log in, log out, permission handling and finally getting user information from request without all this unnecessary code.
view.py
class AnyView(Views):
def get(request):
user=request.user
def post(request):
user=request.user
to implement django authentication check this link:
https://developer.mozilla.org/en-US/docs/Learn/Server-side/Django/Authentication

Im building a crud in Django why is my Update function not working?

Im working on a CRUD in python Django, for CR D no problem, but for Updating it is a mess ! :)
For now I have this first error :
RuntimeError at /updateUser/36
You called this URL via POST, but the URL doesn't end in a slash and you have APPEND_SLASH set. Django can't redirect to the slash URL while maintaining POST data.
I dont understand because I have this in my urls.py :
url(r'^removeUser/(\d+)/$', app.views.removeUser, name='removeUser'),
url(r'^updateUser/(\d+)/$', app.views.updateUser, name='updateUser'),
And for removing user there is no problem !
So okay lets add manually this slash at the end of my url and now I get this error :
NOT NULL constraint failed: app_employee.name
I really don't see what this means
my views.py
def addUser(request):
"""Add new employee"""
if request.method == 'POST':
form = CreationUserForm(request.POST)
newEmployee = Employee()
newEmployee.name = form['employeeName'].value()
newEmployee.email = form['employeeEmail'].value()
newEmployee.save()
return HttpResponseRedirect(reverse('app:home'))
def removeUser(request, id_user):
"""Fire an employee"""
employeeFired = Employee.objects.get(id=id_user)
employeeFired.delete()
return HttpResponseRedirect(reverse('app:home'))
def updateUser(request, id_user):
"""Make a change on an employee"""
employee = Employee.objects.get(id=id_user)
form = UpdateUserForm(request.POST)
employee.name = form['changeEmployeeName'].value()
employee.email = form['changeEmployeeEmail'].value()
employee.save()
return HttpResponseRedirect(reverse('app:home'))
I built update as addUser which works so I dont get the point
Thanks for helping !! :)
see
if I change the views.py by:
def updateUser(request, id_user):
"""Make a change on an employee"""
employee = Employee.objects.get(id=id_user)
# form = UpdateUserForm(request.POST)
employee.name = "static name"
employee.email = "static email"
employee.save()
return HttpResponseRedirect(reverse('app:home'))
it works I get "static name" and "static email"
so the problem is for sure in views.py

Django problem - cannot get the value from the front - query value is none

I've got a problem with an basic searcher app - its about to searching the database for the value that i will be taping in the search bar. I was trying to get the solution from the internet, but there is none or its hard to find something. I was looking for some tut, but none of them works in my app.
Main problem is : ValueError: Cannot use None as a query value. I know that this query is none, but i dont get it why and how.
So, this is my base.html form code:
<form type="GET" action="" accept-charset="utf-8">
<input type="text" name="query" placeholder="Search..."/>
<input type="submit" value='Search' />
</form>
views.py:
class FilmListView(ListView):
model = Film
template_name = 'searcher/home.html'
context_object_name = 'films'
ordering = ['-date_posted']
paginate_by = 3
query = request.GET.get('query')
queryset_list = Film.objects.filter(title__icontains=query)
urls.py:
urlpatterns = [
path('', FilmListView.as_view(), name='search-home'),
path('films/', SearchedFilmListView.as_view(), name='searched-films'),
path('user/<str:username>', UserFilmListView.as_view(), name='user-films'),
path('film/<int:pk>/', FilmDetailView.as_view(), name='film-detail'),
path('film/new/', FilmCreateView.as_view(), name='film-create'),
path('film/<int:pk>/update/', FilmUpdateView.as_view(), name='film-update'),
path('film/<int:pk>/delete/', FilmDeleteView.as_view(), name='film-delete'),
path('about/', views.about, name='search-about'),
]
The other thing in this app is that i have to import request to make it work.
If you got any solution or any tips just help. THX for answers.
By default the get method on a dictionary will return None, so when someone goes to the page without using the form the query value is None trying changing the following line:
query = request.GET.get('query')
to
query = request.GET.get('query', ‘’)
It would be better to change the query in the get_queryset method of the view like so
def get_queryset(self):
query = self.request.GET.get('query')
if query:
queryset = Film.objects.filter(title__icontains=query)
else:
queryset = Film.objects.all()
return queryset
That code wouldn't give you that error. It would give you a NameError, because request is not defined at class level.
You need to put that into the get_queryset method, and also only filter if a value is provided.
class FilmListView(ListView):
...
def get_queryset(self):
qs = super().get_queryset()
query = self.request.GET.get('query')
if query:
qs = qs.filter(title__icontains=query)
return qs

merging a view with template view django

I want that the landing page of my homepage is a form with an input and the user puts in stuff. So I followed a couple of tutorials and now I have this:
views.py:
def create2(request):
if request.method =='POST':
form = LocationForm(request.POST)
if form.is_valid():
form.save()
return HttpResponseRedirect('')
else:
form = LocationForm()
args = {}
args.update(csrf(request))
args['form'] = form
return render_to_response('location/index.html', args)
and in my urls.py:
url(r'^$', 'core.views.create2'),
which works perfectly fine, if I go to 127.0.0.1:8000 I get to index.html and when put in something in the input it gets saved in the database. However, the old part of my homepage looks like this
class LandingView(TemplateView):
model = Location
template_name="location/index.html"
def search
...
and the urls.py:
url(r'^$', core.views.LandingView.as_view(), name='index'),
which has a function search I So my question is, is there a way how I can merge the def create2 into my LandingView. I tried several things, but I am always ending up having the index.html without the input field. I also tried
def create2
...
def search
...
but didn't work.
Does anyone know how to merge that together?
EDIT
Thank you the working solution looks like this now
class Create(CreateView):
model = coremodels.Location
template_name = 'location/test.html'
fields = ['title']
def form_valid(self, form):
form.save()
return HttpResponseRedirect('')
return super(Create, self).form_valid(form)
Depending on the results you are looking for, there are multiple ways to solve this:
1. Use CreateView and UpdateView
Django already provides some classes that render a form for your model, submit it using POST, and re-render the form with errors if form validation was not successful.
Check the generic editing views documentation.
2. Override get_context_data
In LandingView, override TemplateView's get_context_data method, so that your context includes the form you are creating in create2.
3. Use FormView
If you still want to use your own defined form instead of the model form that CreateView and UpdateView generate for you, you can use FormView, which is pretty much the same as TemplateView except it also handles your form submission/errors automatically.
In any case, you can keep your search function inside the class-based view and call it from get_context_data to include its results in the template's context.

Categories

Resources