Django: AttributeError when calling own model method - python

I recently added a new method to my model "News":
def slug(self):
return slugify(self.title)
However I can't seem to call it from anywhere. Imagine I have a News object called n. When trying to call
n.slug()
I always get an error like:
AttributeError: 'News' object has no attribute 'slug'
I'm a total beginner at Django and Python and I'm sure this is just a stupid mistake on my side. By the way I tried restarting the dev server and syncing the db after I added the method, both don't change a thing. Note that I have used model methods like this before without a problem :S
Edit:
Here is the model:
from django.template.defaultfilters import slugify
class News(models.Model):
title = models.CharField(max_length=100)
[...]
def slug(self):
return slugify(self.title)
Here is some example code on how I call the method. I first tried to call it in a template, but it didn't work. Then I changed my view so it just returns the slug, but the error remains. Same when I try it in the shell.
from fbki.models import News
def news_detail(request, slug, news_id):
news = News.objects.get(id = news_id)
return HttpResponse(news.slug())

There are, no errors. Please check what class you by
from fbki.models import News
it looks like you have two copies in project, and modify other class. You check by renaming your class News to News1. It you will same error - I'm right.

I've had some errors similar to this.
I believe that the problem is an inconsistency between your model and the actual schema in your database.
Run manage.py sql myapp and verify the contents match what is in sql> show schema (etc.)
If they don't match, you have to use your SQL client and drop the old table so that you can re-run manage.py syncdb to make them match again.
Your method should work once the schema are present.

Related

Getting an attribute error in django.how do i resolve this?

Getting an attribute error at a model in django. When I tried to call the model.get_absolute_url at my model_list templates.it says model has no attributen "id"
while in the model,i ve also written both the url mapper and the view function correctly,including the detals templates
the exception was pointing to this reverse line
This is the the model in models.py file
class Post(models.Model):
title=models.CharField(max_length=200,help_text="Write your title",primary_key=True)
caption=models.TextField(help_text="Write something")
image=models.FileField(blank=True)
post_date=models.DateField(auto_now=True)
class Meta:
ordering=['post_date']
def __str__(self):
return self.title
def __str__(self):
return self.caption
def get_absolute_url(self):
return reverse('post-detail', args=[str(self.id)])
#here is the url path
urlpatterns +=[
path('posts',views.PostListView.as_view(),name="post-list"),
path('post/<int:pk>',views.PostDetailView.as_view(),name="post-detail")
]
Expanding on Willem Van Onsem's comment, rewrite the model as you already did, from your last comment,
class Post(models.Model):
title=models.CharField(max_length=200,help_text="Write your title")
caption=models.TextField(help_text="Write something")
image=models.FileField(blank=True)
post_date=models.DateField(auto_now=True)
class Meta:
ordering=['post_date']
def __str__(self):
return self.title
def __str__(self):
return self.caption
def get_absolute_url(self):
return reverse('post-detail', args=[str(self.id)])
#here is the url path
urlpatterns +=[
path('posts',views.PostListView.as_view(),name="post-list"),
path('post/<int:pk>',views.PostDetailView.as_view(),name="post-detail")
]
Now to handle the error you get after doing this. If you're in development and have no data in your database that you need to keep you can drop and recreate the entire database and re run the commands:
python manage.py makemigrations
python manage.py migrate
or,
python manage.py flush
Source: https://docs.djangoproject.com/en/4.0/ref/django-admin/#flush
But note that this will erase all the data from your database. If you need to keep the data, checkout the accepted answer by S. here:
Unload your data into JSON files. Use Django's own internal
django-admin.py tools for this. You should create one unload file for
each that will be changing and each table that depends on a key which
is being created. Separate files make this slightly easier to do.
Drop the tables which you are going to change from the old schema.
Tables which depend on these tables will have their FK's changed; you
can either update the rows in place or -- it might be simpler -- to
delete and reinsert these rows, also.
Create the new schema. This will only create the tables which are
changing.
Write scripts to read and reload the data with the new keys. These are
short and very similar. Each script will use json.load() to read
objects from the source file; you will then create your schema objects
from the JSON tuple-line objects that were built for you. You can then
insert them into the database.
You have two cases.
Tables with PK's change changed will be inserted and will get new
PK's. These must be "cascaded" to other tables to assure that the
other table's FK's get changed also.
Tables with FK's that change will have to locate the row in the
foreign table and update their FK reference.
Alternative.
Rename all your old tables.
Create the entire new schema.
Write SQL to migrate all the data from old schema to new schema. This
will have to cleverly reassign keys as it goes.
Drop the renamed old tables.

Django import-export, only export one object with related objects

I have a form which enables a user to register on our website. Now I need to export all the data to excel, so I turned towards the import-export package. I have 3 models, Customer, Reference and Contact. The latter two both have a m2m with Customer. I also created Resources for these models. When I use Resource().export() at the end of my done() method in my form view, it exports all existing objects in the database, which is not what I want.
I tried googling this and only got one result, which basically says I need to use before_export(), but I can't find anywhere in the docs how it actually works.
I tried querying my customer manually like:
customer = Customer.objects.filter(pk=customer.id)
customer_data = CustomerResource().export(customer)
which works fine but then I'm stuck with the related references and contacts: reference_data = ReferenceResource().export(customer.references) gives me an TypeError saying 'ManyRelatedManager' object is not iterable. Which makes sense because export() expects an queryset, but I'm not sure if it's possible getting it that way.
Any help very appreciated!
One way is to override get_queryset(), you could potentially try to load all related data in a single query:
class ReferenceResource(resources.ModelResource):
def __init__(self, customer_id):
super().__init__()
self.customer_id = customer_id
def get_queryset(self):
qs = Customer.objects.filter(pk=self.customer.id)
# additional filtering here
return qs
class Meta:
model = Reference
# add fields as appropriate
fields = ('id', )
To handle m2m relationships, you may be able to modify the queryset to add these additional fields.
This isn't the complete answer but it may help you make progress.

How to solve err 'dict' object has no attribute 'save' when trying to make an update on DB

I'm getting a problem working with django and its model system. I'm new working with django and I'm stuck since I've probably making the things wrong.
I'm trying to make an update to my DB and I get this error:
"'dict' object has no attribute 'save'"
I'm only trying to set a field to be active or inactive depending on a check input on my html.
I'm sending the right value on the request.
I'm getting a dictionary instead of a model object, but I don't really know how to change this, I think I followed the django docs. step by step.
models.py:
from django.db import models
class Flags(models.Model):
num = models.IntegerField(null=False)
deliver= models.CharField(max_length=1, null=False)
class Meta:
db_table ="FLAGS"
views.py:
from django.http import HttpResponse
from Logistic.models import Flags
def updateDisponibilidad(request):
flag = request.GET.get("flag")
print(flag)
disp = Flags.objects.using('default').values('num', 'deliver').get(num__exact=1)
print(disp)
disp['deliver'] = str(flag)
disp.save()
return HttpResponse(disponibilidad)
Django docs. says I can acces to the values putting (in this case) disp.deliver, but when I do that, i get a different error:
'dict' object has no attribute 'deliver'
It would be fantastic if anyone can help me so I be able to use this code:
disp.deliver = flag
disp.save()
And work with that.
This is due to the .values() in your query, if you want to obtain a Flags object, you should remove that, so:
def updateDisponibilidad(request):
flag = request.GET.get("flag")
disp = Flags.objects.using('default').get(num=1) # no .values()
print(disp)
disp['deliver'] = str(flag)
disp.save()
return HttpResponse(disponibilidad)
If you use .values(), you retrieve a dictionary. Here we retrieve a Flags object, and model objects have a .save() method to update the object in the database.
If you want to render the content to a JSON response, you should use a serializer, not use Django ORM features for that.
Furthermore if you update entities, one typically uses a POST, PUT, PATCH, etc. request, not a GET request.

JSONField getting saved as string django

I have a django model like below:
from jsonfield import JSONField
class SCUser(User):
address = JSONField(blank=True,null=True)
When I save a json in this address it gets saved as string.
Here is a code snippet:
appuser.address = {"state":""}
appuser.save()
Now if I try to retrieve appuser.address it gives me
>>>appuser.address
>>>u'{"state":""}'
>>>appuser.save()
>>>appuser.address
>>>u'"{\\"state\\":\\"\\"}"'
And it gets recursive.
What am I missing here?
Edit:
The AppUser inherits from SCUser model.
I met this problem when I am using a non-Autofield key as the model's primary key and I found some issues which is still open on github related to this problem.
https://github.com/dmkoch/django-jsonfield/issues/92
https://github.com/dmkoch/django-jsonfield/issues/101
I solved this problem by define a pk property in the model. I don't known is there any side effects by using this solution.
class SCUser(User):
....
#property
def pk(self):
return self.id # your pk
Please try:
appuser.address = {"state":""}
appuser.save()
appuser.get_data_json()

Can't call save() in Django Model? Gets: AttributeError: 'unicode' object has no attribute 'save'

Thanks for the time for helping me out.
I'm pretty new to django and python.
So I have a model, that I'm trying to pull some data from another model to build out a landing page of sorts. I was trying to make it completely customizatable in the admin but I discovered for what I wanted do I was going to have to involve AJAX. I've scrapped that, and resorted to mostly removing the admin customization because this is really just for my own personal site.
So to boil down the overall goal:
There are many "gallery" pages I want to pull the first image from
Each gallery on my "landing" page will be a single image from each
gallery, title, and url to the gallery.
This is part of my model:
class AggeragateImages(Orderable):
aggeragate = models.ForeignKey("AggeragatePage", related_name="thumbnails")
gallery_titles = models.CharField(editable=False, max_length=1000)
gallery_slug = models.CharField(editable=False, max_length=1000)
def getGallery():
"""
Returns PK of all Gallery content type pages
"""
galleryPK = []
for e in Page.objects.filter(content_model='gallery'):
galleryPK.append(e.pk)
return galleryPK
galleryPK = getGallery()
for e in galleryPK:
gallery_titles = Gallery.objects.get(pk=e).titles
gallery_titles.save()
gallery_slug = Gallery.objects.get(pk=e).slug
gallery_slug.save()
def __unicode__(self):
return self.name
However why I run a syncdb I get: AttributeError: 'unicode' object has no attribute 'save'
I've also trying doing this through the interactive shell to, and I get the same error when calling 'save()'
Am I really far off base? I really appreciate your help.
The problem is at:
gallery_titles = Gallery.objects.get(pk=e).titles
gallery_titles.save()
When you do Gallery.objects.get(pk=e), it returns you a model instance, however then you retrieve it's titles attribute which I guess is a string (unicode). So at that point, gallery_titles is a sting which you try to save on the next line, but unicode class does not have a method save which causes an error.
As a side note, it's probably not the best idea to put logic code directly inside a class definition. You can factor your logic into class methods which would be much more appropriate. When you call a class method inside it's definition you are still defining a class attribute.

Categories

Resources