I'm trying to learn Python and Django by implementing an online forum. Right now, I'm trying to set the default value of the post title to "Re:" + thread.title, but I can't seem to do it.
I've searched for anything like this but nothing seems to answer my problem.
Here's my code (models.py):
from django.db import models
class Thread(models.Model):
title = models.CharField(max_length=50)
def __unicode__(self):
return u'[id=%s]%s' % (self.id, self.title)
class Post(models.Model):
thread = models.ForeignKey(Thread)
title = models.CharField(max_length=50)
post_date = models.DateTimeField(auto_now_add=True)
content = models.TextField()
def __init__(self):
super(Post, self).__init__()
if not self.title:
self.title = "Re: %s" % self.thread.title
def __unicode__(self):
return u'%s::[id=%s]%s' % (self.thread, self.id, self.title)
I hope someone can help me.
Regards,
Chad
You probably want to set the default value in the overridden save method. Your __init__ code doesn't work because at that point self.thread is not set yet.
Related
I'm trying to print the title of the first object in my DB in django. However, when I enter the command
Project.objects.all() in the shell, it just returns the following:
<QuerySet [<Project: Project object (1)>]>
This is my code:
# Create your models here.
class Project(models.Model):
title = models.CharField(max_length=100)
progress = models.FloatField(default=0)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
def __str__(self):
return self.title
class Task(models.Model):
project = models.ForeignKey(Project, on_delete=models.CASCADE)
title = models.CharField(max_length=100)
priority = models.SmallIntegerField(default=0)
open_date = models.DateTimeField()
close_date = models.DateTimeField()
status = models.SmallIntegerField(default=0)
def __str__(self):
return self.title
The str part doesn't seem to be doing anything, even when I purposely misspell something, no error is returned. There seems to be a few threads with similar issues with no accepted solutions as of yet.
I would like it to return the title that I've entered, which should be <QuerySet [<Project: My First Project>]>.
Thanks in advance for your help.
You are passing self.title to the str method. Just pass self and then return the title.
def __str__(self):
return self.title
Typically, the repr of underlying objects is used when printing their containers (all the built-in collections types do this for instance). Change the name of the method from __str__ to __repr__ and it should fix your issue. __str__ already defaults to using the __repr__ method if no other __str__ is defined, so it'll still work in other stringifying scenarios.
What to do? I kept restarting my server but it still didn't work. This is the whole code snippet of my models.py:
from django.db import models
class Blog(models.Model):
title = models.CharField(max_length=50)
pub_date = models.DateField(auto_now_add=True)
# publication date
image = models.ImageField(upload_to='images/')
summary = models.CharField(max_length=200)
body = models.TextField()
def __str__(self):
return self.title
But the names of each objects are still not changing:
Put the method inside the Blog Model as following:
models.py
from django.db import models
class Blog(models.Model):
def __str__(self):
return self.title
Your def str(self) is not indented inside your model class. Make the changes and it will work.
class modelClass(models.Model):
#your properties
#below method should be indented
def __str__(self):
return self.property
Could you try below?
class Blog(models.Model):
........
def __str__(self):
return str(self.title)
I would like to show one attribute from another class. The current class has a foreign key to class where I want to get the attribute.
# models.py
class Course(models.Model):
name = models.CharField(max_length=100)
degree = models.CharField(max_length=15)
university = models.ForeignKey(University)
def __unicode__(self):
return self.name
class Module(models.Model):
code = models.CharField(max_length=10)
course = models.ForeignKey(Course)
def __unicode__(self):
return self.code
def getdegree(self):
return Course.objects.filter(degree=self)
# admin.py.
class ModuleAdmin(admin.ModelAdmin):
list_display = ('code','course','getdegree')
search_fields = ['name','code']
admin.site.register(Module,ModuleAdmin)
So what i'm trying to do is to get the "degree" that a module has using the "getdegree". I read several topics here and also tried the django documentation but i'm not an experienced user so even I guess it's something simple, I can't figure it out. Thanks!
It is pretty straight forward.
Try this:
def getdegree(self):
return self.course.degree
Documentation here
You can do this safely because course is not a nullable field. If it were, you should have checked for existence of object before accessing its attribute.
In my blog I decided to allow users to edit posts (I am using Django), but I am not sure what is the right implementation for my models to do that. Is a good idea to use multi-table inheritance as my code below? I also want to keep track of all the posts, originals as the every new edited as well.
class Post(models.Model):
title = models.CharField(max_length=500)
text = models.TextField()
creation_date = models.DateTimeField(auto_now_add=True)
user = models.ForeignKey(User)
def __unicode__(self):
return "%s %s by %s" % (self.title, self.creation_date, self.user)
class Edit(Post):
edited_date = models.DateTimeField(auto_now_add=True)
editor = models.OneToOneField(User)
def __unicode__(self):
return "%s edited by %s" % (self.convention, self.login)
What you need is version control. There are apps that can implement it. But if you want to do it yourself, then your Edit model must have a reference to the Post models. And must point to a specific post corresponding to the author of that edit. That necessarily means you have to create a Post instance every time a post is saved and you must point to that new instance from the Edit instance.
Something like this, but may need more work -
class Post(models.Model):
title = models.CharField(max_length=500)
text = models.TextField()
creation_date = models.DateTimeField(auto_now_add=True)
edited_date = models.DateTimeField(auto_now_add=True)
author = models.ForeignKey(User)
def __unicode__(self):
return "%s at %s by %s" % (self.title, self.creation_date, self.author.first_name)
class Edit(models.Model):
creation_date = models.DateTimeField(auto_now_add=True)
editor = models.ForeignKey(User)
post = models.ForeignKey(Post)
def __unicode__(self):
return "%s edited by %s" % (self.post.title, self.editor.first_name)
I am working through the Django tutorials, and now I am at creating a poll.
The code below works fine until I want to create choices, where for some reason I always get this error message:
line 22, in __unicode__
return self.question
AttributeError: 'Choice' object has no attribute 'question'
What am I doing wrong?
Here's my code:
import datetime
from django.db import models
class Poll(models.Model):
question = models.CharField(max_length=200)
pub_date = models.DateTimeField('date published')
def __unicode__(self):
return self.question
def was_published_today(self):
return self.pub_date.date() == datetime.date.today()
class Choice(models.Model):
poll = models.ForeignKey(Poll)
choice = models.CharField(max_length=200)
votes = models.IntegerField()
def __unicode__(self):
return self.question # this is line 22
The __unicode__ method on the Choice model should look something like:
def __unicode__(self):
return self.poll.question
question attribute does not exist on the Choice model, you need to reach for it over the poll foreign key field.
Don't forget to check out Django's great documentation that shows many examples on how to handle many to one relationships.
Edit
It would probably make more sense to return self.choice in Choice model __unicode__ method so it outputs the actual choice not the Poll question.
def __unicode__(self):
return self.choice
To follow up on rebus's answer, the tutorial actually says to add different returns to each model:
class Poll(models.Model):
# ...
def __unicode__(self):
return self.question
class Choice(models.Model):
# ...
def __unicode__(self):
return self.choice
You had 'self.question' as the return for both - I'm thinking you made the same copy/paste error I did, or the tutorial previously had that error ;-)
It should be:
def __unicode__(self):
return self.poll.question
Because poll is a related model that contains the question.
This is due to a Human Brain error or a copy/paste error. We/You thought that both functions were same and copy-pasted the same code for both, but there was one word different in both.
replace question to choice in line 22