Django 'function' object has no attribute 'objects' - python

My apps allow you to like a picture then it redirects you to the same page
I get then error when I try to like a picture I can create a like objects with the shell prompt but why I get this error? thank for helping me
AttributeError at /like/3/
function' object has no attribute 'objects'Request Method: GET
Request URL: http://127.0.0.1:8000/like/3/
Exception Value: 'function' object has no attribute 'objects'
Traceback:
File "C:\Python26\Lib\site-packages\django\core\handlers\base.py" in get_response
111. response = callback(request, *callback_args, **callback_kwargs)
File "C:\o\mysite\pet\views.py" in Like
195. new_like, created = Like.objects.get_or_create(user=request.user, picture_id=picture_id)
This is parts of my views.py
def Like(request,picture_id):
pid = picture_id
new_like, created = Like.objects.get_or_create(user=request.user, picture_id=picture_id)
p = Picture.objects.get(pk=pid)
if created:
HttpResponseRedirect(reverse('world:url_name'))
else:
HttpResponseRedirect(reverse('world:url_name'))
My URLconf:
url(
Parts of my model:
r'^like/(?P\d+)/$',
'pet.views.Like',
name = 'Like'
),
My boat.html
{% if picture %}
<ul>
{% for pet in picture %}
<li><b>description</b> = {{ pet.description}}<br/>
{% if pet.image %}
<li>
<a href ="{% url world:Like pet.id %}">
<img src= "{{ pet.image.url }}" style="cursor:pointer">
</a>
<li>
{% endif %}
{% endfor %}
</ul>
{% endif %}
Add Pictures to your board<br/>
My models.py
class Picture(models.Model):
user = models.ForeignKey(User)
board = models.ForeignKey(Board,blank=False,null=False)
image = models.FileField(upload_to="images/",blank=True)
description = models.TextField()
is_primary = models.BooleanField(default=False)
def __unicode__(self):
return self.description
class Like(models.Model):
user = models.ForeignKey(User)
picture = models.ForeignKey(Picture)
created = models.DateTimeField(auto_now_add=True)

your view function name is defined as Like and your model is named Like
you define Like as a function so when you go to access Like.objects python does not see your model Like but the function Like
you could rename your view function
url(r'^like/(?P\d+)/$', 'pet.views.change_name_no_conflict', name = 'Like' )
def change_name_no_conflict(request,picture_id):
pass

Model name and view name shouldn't be same.

This is because your function name in view.py and model name in models.py are the same.
You can change the function name or model name.
Another solution is:
from .models import modelname as modelname2
def modelname(request):
obj_list_ads = modelname2.objects.all()
in this code function name is modelname.

I got this same error when doing
from django.contrib.auth import get_user_model
User = get_user_model
adding () solved the error:
from django.contrib.auth import get_user_model
User = get_user_model()

function name and model name does depend on name, function name should be same as url name we define url in urls.py model name depend on function data member, its means as for example when we take data from user and save in database then we call that object from its model name ex= u_data = registration() ,this is used for user data seve and define that fun where we send data to save means target url and in its related view.

I hit this error because my view's query set looked like this:
class IngredientList(generics.ListAPIView):
queryset = Ingredient.objects.all # This line is wrong
serializer_class = IngredientSerializer
I fixed it by adding a set of parenthesis to the queryset line:
class IngredientList(generics.ListAPIView):
queryset = Ingredient.objects.all() # Fixed
serializer_class = IngredientSerializer

Define object:
objects = models.Manager()
Your error will solve!

Related

Django: How to implement user profiles?

I'm making a Twitter clone and trying to load profile pages. My logic was to start simple and find all tweets that match a certain author and load those tweets on a page as the user's profile. I really don't know where to start.
urls.py
url(r'^users/(?P<username>\w+)/$', views.UserProfileView.as_view(), name='user-profile'),
models.py
class Howl(models.Model):
author = models.ForeignKey(User, null=True)
content = models.CharField(max_length=150)
views.py
class UserProfileView(DetailView):
"""
A page that loads howls from a specific author based on input
"""
model = get_user_model()
context_object_name = 'user_object'
template_name = 'howl/user-profile.html'
user-profile.html
{% block content %}
<h1>{{user_object.author}}</h1>
{% endblock %}
I'm currently getting an error that says "Generic detail view UserProfileView must be called with either an object pk or a slug." whenever I try something like localhost:8000/users/
I also went on the shell and tried
Howl.objects.filter(author="admin")
But got
ValueError: invalid literal for int() with base 10: 'admin'
Foreign key require model object or primary key of object.
pass the id of object whose username is "admin". use
Howl.objects.filter(author=1)
instead of
Howl.objects.filter(author="admin")
or you can use this one also
user = User.objects.get(username = "admin")
Howl.objects.filter(author=user)

How can I properly use related_name in django models to get back the class name?

I have an application called "school" inside one of my django projects.
Below is the code of models.py
from django.db import models
class Student(models.Model):
name = models.CharField(max_length=255)
birthday = models.DateField(blank=True)
class Class(models.Model):
name = models.CharField(max_length=255)
student = models.ForeignKey(Student,related_name='classes',null=True)
def __str__(self):
return self.name
And now, views.py:
from django.shortcuts import render
from .models import *
def test(request):
obj2 = Student.objects.get(name='john')
return render(request,'test/list.html', {'obj2':obj2} )
And finally, my template looks like this:
{% block content %}
<h2>
{{ obj2.classes }}
</h2>
{% endblock %}
In my template, I am using obj2.classes (i.e., responseobject.related_name). I want it to print the class name.
However when I access the site at http://127.0.0.1:8000/shop/ ,
it gives me this output:
shop.Class.None
How will I get the output as only "Class", that is the class name?
Would obj2._meta.get_field('classes').related_model.__name__ do the job? This will work on your view only, not on the template.
def test(request):
obj2 = Student.objects.get(name='john')
classes_name = obj2._meta.get_field('classes').related_model.__name__
return render(request, 'test/list.html',
{'obj2':obj2, 'classes_name': classes_name})
Using this method, you avoid to use obj2.classes, which hits the database to retrieve the object.
You can also get the verbose_name with obj2._meta.get_field('classes').related_model._meta.verbose_name.

NoReverseMatch Error Related to get_context_data

I'm getting a NoReverseMatch error resulting from my template url tag. But I'm using class based views, and the error is related to using the get_context_data function. If I comment out the get_context_data function, I don't get the error.
Here's the error I'm getting:
NoReverseMatch at /task-manager/update-project/e75eac16-711b-4fb7-9b08-7516cae8433f/
Reverse for 'update-project' with arguments '('',)' and keyword arguments '{}' not found. 1 pattern(s) tried: ['task-manager/update-project/(?P[a-zA-Z0-9_-]+)/$']
And then:
Error during template rendering
In template [projectdir]/[appdir]/templates/tasks
/update-project.html, error at line 7
Reverse for 'update-project' with arguments '('',)' and keyword arguments '{}' not found. 1 pattern(s) tried: ['task-manager/update-project/(?P<pk>[a-zA-Z0-9_-]+)/$']
Here is the update-project.html:
{% extends "tasks/base.html" %}
{% block content %}
<h2>Update a project</h2>
<div class="form">
<form action="{% url 'task_manager:update-project' project.id %}" method="POST">
{% csrf_token %}
{{ form }}
<BR><BR>
<input type="submit" value="Submit" />
</form>
</div>
....
My application's urlconf is tasks/urls.py:
from django.conf.urls import url
from . import views
urlpatterns = [
# Index
url(r'^$', views.TaskView.as_view(), name='index'),
# TASKS
# E.g., /task/3j243o-Ofjdsof-3123
url(r'^tasks/(?P<pk>[0-9a-zA-Z_-]+)/$', views.TaskDetailView.as_view(), name='task_detail'),
# Adding tasks
url(r'^add-task/$', views.TaskCreate.as_view(), name='add_task'),
# Update/view tasks
url(r'^view-task/(?P<pk>[0-9a-zA-Z_-]+)/$', views.TaskUpdate.as_view(), name='view_task'),
# PROJECTS
# E.g., /project/234jf0we-324skl-34j
url(r'^projects/(?P<pk>[a-zA-Z0-9_-]+)/$', views.ProjectDetailView.as_view(), name='project_detail'),
# Adding projects
url(r'^add-project/$', views.ProjectCreate.as_view(), name='add_project'),
# Updating/viewing Projects
url(r'^update-project/(?P<pk>[a-zA-Z0-9_-]+)/$', views.ProjectUpdate.as_view(), name='update-project')
]
The relevant part of views.py is:
class ProjectUpdate(UpdateView):
"""
This will be used to view and update projects
"""
template_name = 'tasks/update-project.html'
model = Project
context_object_name = 'project'
fields = ['name','status', 'purpose', 'vision', 'big_steps', 'context', 'priority', 'due_date', 'related_project']
def get_context_data(self, **kwargs):
"""
This pulls in related tasks to display them as links.
"""
# Call base implementation first to get a context
context = super(ProjectUpdate, self).get_context_data(**kwargs)
# TO DO: Add in querysets of related tasks
context['related_tasks'] = Task.objects.all()
And relevant part of model.py:
class Project(models.Model):
"""
Project is for any multi-step thing that needs to be done. Tasks
will be associated with it.
"""
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
name = models.CharField(max_length=200)
purpose = models.TextField(blank=True)
"""What is my purpose with this task?"""
vision = models.TextField(blank=True)
"""Vision refers to what the task will look like when successfully
completed"""
big_steps = models.TextField(blank=True)
"""What are the big steps (not task-level steps) that need to be
completed? Maybe split this out into a new class, similar to tasks"""
status = models.CharField(max_length=30, choices=STATUSES, default='pending')
created_date = models.DateTimeField(auto_now_add=True)
updated_date = models.DateTimeField(auto_now=True)
context = models.CharField(max_length=50, choices=CONTEXTS)
priority = models.CharField(max_length=50, choices=PRIORITIES)
due_date = models.DateTimeField(blank=True, null=True)
related_project = models.ForeignKey("self", blank=True, null=True)
def __str__(self):
return self.name
def get_absolute_url(self):
return reverse('task_manager:project_detail', kwargs={'pk': self.pk})
What is weird is that if I comment out the get_context_data function in my view, it works just fine.
It looks like you have forgotten to return the context. Without the return statement, it implicitly returns None. This causes the reverse match, because the url tag gets None instead of the required project id.
def get_context_data(self, **kwargs):
"""
This pulls in related tasks to display them as links.
"""
# Call base implementation first to get a context
context = super(ProjectUpdate, self).get_context_data(**kwargs)
# TO DO: Add in querysets of related tasks
context['related_tasks'] = Task.objects.all()
return context

Simple URL mapping issue

I would like to map my urls.py to include this url: http://127.0.0.1:8000/activity/Arts%20&%20Crafts/member
This url was created by this line of code in my activity.html template:
<li><a href='/activity/{{ activity.name }}/member'>{{ activity.name }}</a></li>
Arts & Crafts is the name of an object I've created under the model Activity:
(models.py)
class Activity(models.Model):
name = models.CharField(max_length=50)
comments = models.CharField(max_length=300, null=True, blank=True)
questions = models.ManyToManyField(Question, blank=True)
pub_date = models.DateTimeField('Date published')
def __str__(self):
return self.name
Right now, my url in urls.py looks like this:
url(r'^activity/{{ models.Activity.name }}/member/$', views.SelectView.as_view(), name='select_member'),
But it doesn't work. When I try to go to http://127.0.0.1:8000/activity/Arts%20&%20Crafts/member; I get a 'Page Not Found' error saying "The current URL, activity/Arts & Crafts/member, didn't match any of these."
Can someone tell me what is wrong with my url, and how to fix it? Thank you.
Extra info--
urls.py:
from django.conf.urls import url
from . import views
urlpatterns = [
url(r'^$', views.IndexView.as_view(), name='index'),
url(r'^detail/$', views.DetailView.as_view(), name='detail'),
url(r'^activity/$', views.ActivityView.as_view(), name='activity'),
url(r'^activity/{{ models.Activity.name }}/member/$', views.SelectView.as_view(), name='select_member'),
]
views.py:
class SelectView(generic.ListView):
template_name = 'expcore/select_member.html'
model = Activity
Update your urls.py to capture the name of the activity:
url(r'^activity/(?P<activityname>[^/]+)/member/$',
views.SelectView.as_view(), name='select_member'),
The regex will capture the name of the activity and pass it as a keyword arg to the appropriate method (get or post) of your view function. In that function you can then retrieve the activity name from kwargs['activityname'] and then retrieve the activity object with the associated name via Activity.objects.get(name=kwargs['activityname']).
Then in your template you can generate the url using
<li>{{ activity.name }}</li>
It is not the right way of defining a url. I recommend reading the relevant section in the Django documentation about how to create a url for a view.
url(r'^activity/(?P<name>\W+)/member/$', views.SelectView.as_view(), name='select_member'),
Apart from that, there is another issue that needs to be addressed. Since you need to fetch the object by its name, you need to change slug_url_kwarg and slug_field to name in your view class:
class SelectView(generic.ListView):
template_name = 'expcore/select_member.html'
model = Activity
slug_url_kwarg = 'name'
slug_field = 'name'
Make sure to always leverage {% url %} template tag when creating a url in your template:
<li>{{ activity.name }}</li>
I think that a model variable should be used in a template, but you cannot put a model variable in a url(). You should use:
url(r'/activity/(?P<activityid>[0-9a-zA-z\.\_]+)/member/$', views.SelectView.as_view),
and then inspect "activityid" to verify whether it corresponds to a known and existing page and eventually visualize it.
Refer this link
Your urls.py
url(r'^activity/{{ models.Activity.name }}/member/$', views.SelectView.as_view(), name='select_member'),
Change it to
url(r'^activity/(?P<activity_name>[^/]+)/member/$', views.SelectView.as_view(), name='select_member'),
And while printing the path in template use
<li>{{ activity.name }}</li>

Django - logic behind displaying relational tables in template

I have multiple related tables defined in my Django models:
# first models.py
from django.db import models
class Character(models.Model):
first_field = models.DateTimeField()
second_field = models.TextField()
# second models.py
from django.db import models
class Op(models.Model):
fk_character = models.ForeignKey('Character')
some_field = models.DateTimeField()
other_field = models.TextField()
class Participant(models.Model):
fk_op = models.ForeignKey('Op')
fk_character = models.ForeignKey('Character')
some_other_field = models.IntegerField(default=0)
For now, I'm sending this data from a view to template in a way like this:
# views.py
from django.shortcuts import render_to_response
from django.template import RequestContext
from second.models import MainModel
def home(request):
data = Op.objects.filter(some_field__isnull=True).order_by('-date')
rc = RequestContext(request, {'data':data})
return render_to_response('index.html', rc)
In this way I do have all the Op related data I need in my index.html template, but I'm struggling with logic to display this data in my template in a specific way. For example:
display a list of all Ops,
for each list item, check if Character is also a Participant in current Op item,
if it isn't, display some button, if it is than don't display the button
I know that template shouldn't handle any programming logic, but I'm also not sure what would be the best approach to solve this. Should I do all the logic in my view and construct a new object and send that object to my view or is there an easy way to solve this in template with current object I'm sending?
Update your model:
class Op(models.Model):
fk_character = models.ForeignKey('Character')
some_field = models.DateTimeField()
other_field = models.TextField()
def check_if_participant(self):
return bool(self.participant_set.all())
Display list of all Ops:
{% for op in data %}
{{op.some_field}}
{% if op.check_if_participant %}Yes - Character is participant {% endif %}
{% endfor %}

Categories