I am working on a project where I want to create a slug for each post based on its title. Is it possible to generate a slug in such a way that it will be unique to the post, but will not change even if the title of the post is changed? I am using the model provided in the file 'model.py'. Can you provide guidance on how to accomplish this?
class Post(models.Model):
username = models.ForeignKey(UserProfile, on_delete=models.CASCADE)
description = models.CharField(('Description'),max_length=250)
title = models.CharField(('Content Title'), max_length=250)
create_date = models.DateTimeField(default = timezone.now)
image_data = models.ImageField(upload_to='User_Posts', height_field=None, width_field=None, max_length=None)
slug = (title)
def __str__(self):
return self.title
I recommend checking out the Django documentation for slugify. You will need to override the save method of your model to do this, so your new code will most likely look something like this:
from django.utils.text import slugify
slug=models.SlugField()
def save(self,*args,**kwargs):
self.slug=slugify(self.title)
super(Post,self).save(*args,**kwargs)
I would keep in mind the unique parameter that you can set to either true or false in your slugfield.
Related
I have been having a hard time accomplishing this task and it seems that I cannot get help anywhere I turn. I am trying to send Memos to specific user groups in Django. Each user in each group should receive the Memo and be able to change the BooleanField to True to signify that they have read it.
I then need to be able to access the amount of users which received and have marked the BoolenField as True so I can create a table in a template which says [3/31 Read] and such.
I would like to not use GenericForeignkeys if possible and I would like to keep it as one Model if possible but I know that may not work. Currently I was trying this:
class Memo(models.Model):
title = models.CharField(max_length=100)
content = models.TextField()
date_time = models.DateTimeField(default=timezone.now)
sender = models.ForeignKey(User, on_delete=models.CASCADE)
receiver = models.ManyToManyField(Group)
def __str__(self):
return self.title
def get_absolute_url(self):
return reverse('memos-detail', kwargs={'pk': self.pk})
I was going to access each user (receiver) within the group which is selected on the MemoCreateForm then apply that user to this model:
class ReceivedMemo(models.Model):
memo = models.ForeignKey(
Memo, related_name='user_memos', on_delete=models.CASCADE)
receiver = models.ForeignKey(
User, related_name='memos', on_delete=models.CASCADE)
read = models.BooleanField(default=False)
Then I was going to try to filter the ReceivedMemos by memo to see if each receiver has read the memo or not. But this is starting to get complicated and I am not sure if it will work. Am I going about this the right way? Or should I be able to have one Model such as:
class Memo(models.Model):
title = models.CharField(max_length=100)
content = models.TextField()
date_time = models.DateTimeField(default=timezone.now)
sender = models.ForeignKey(User, on_delete=models.CASCADE)
receiver = models.ForeignKey(User, on_delete=models.CASCADE)
read = models.BooleanField(default=True)
Seems that each object would have the BooleanField applied to the object and not the user though.
The ReceivedMemo model seems more appropriate rather than the read bit, but the issue with this approach is that whenever you create a new Memo you need to also create lots of (for every User in the Group) ReceivedMemo objects with read=False? This seems pointless. Maybe you can just store the Users which actually read this thing, and for everyone that's left, consider he has not read it. I.e.
class Memo(models.Model):
title = models.CharField(max_length=100)
content = models.TextField()
date_time = models.DateTimeField(default=timezone.now)
sender = models.ForeignKey(User, on_delete=models.CASCADE)
receiver = models.ManyToManyField(Group)
read_by = models.ManyToManyField(User)
These are two models in my Django app :
models.py
class Posts(models.Model):
title = models.CharField(max_length=200, blank=True)
author = models.ForeignKey(user,on_delete=models.CASCADE,default=None, blank=True)
content = models.TextField()
class Unposted(models.Model):
article = models.ForeignKey(Posts, on_delete=models.CASCADE)
upload_at = models.DateTimeField(default=datetime.now, blank=True)
I'm trying to retrieve data from Posts using an API request to Unposted.
Here's what I have until now but I'm unsure how to get data from the Posts model. Right now I just get a JSON response with only the upload_at field.
resources.py
class UnpostedResource(ModelResource):
class Meta:
queryset = Unposted.objects.all()
resource_name = 'unposted'
If I'm not wrong, u can just import your Posts model and then just by for loop make an array with posts models using foreign key from unposted to filter your posts =) Sounds weird and I'm not sure about effectiveness, but looks pretty nice. It will look smth like:
queryset = Posts.objects.filter(article_in=[get(i.article) for i in Unposted.objects.all()])
In the case, Posts is a foreignkey of Unposted, thus you need to define foreignkey field in the resource for the corresponding field in model, this tutorial maybe can help you.
I am building a simple forum application and I need some help with counting foreign key objects via through relation.
Let's say my models look like this:
class Forum(models.Model):
title = models.CharField(max_length=255)
description = models.TextField()
slug = models.SlugField(unique=True, blank=True)
class Thread(models.Model):
title = models.CharField(max_length=255)
forum = models.ForeignKey(to=Forum, related_name='threads')
slug = models.SlugField(unique=True, blank=True)
class Post(models.Model):
body = models.TextField()
author = models.ForeignKey(User)
thread = models.ForeignKey(to=Thread,related_name='posts')
Now we create forum object.
forum = Forum.objects.get(slug=forum)
We can count the number of threads inside forum like this: forum.threads.count()
My question is, how can i count all the posts in a forum?
I've tried something like all_posts = forum.thredas.posts.count() but as expected it didn't work.
Thanks!
Generally in Django it is a good principle that when you want to do something with a model, you should start your query from that model. So, since you need to count posts, you should start with the Post model.
From there you can use the double-underscore syntax to filter to the particular Forum you want.
forum_posts = Post.objects.filter(thread__forum=my_forum)
forum_post_count = forum_posts.count()
I have two different models.
class MessageArchive(models.Model):
from_user = models.CharField(null=True, blank=True, max_length=300)
archived_time = models.DateTimeField(auto_now_add=True)
label = models.ForeignKey(MessageLabel, null=True, blank=True)
archived_by = models.ForeignKey(OrgStaff)
tags = TaggableManager()
Now say, I have defined spam, todo, urgent tags for messages.
and then I have another model:
class PersonArchive(models.Model):
from_user = models.CharField(null=True, blank=True, max_length=300)
archived_time = models.DateTimeField(auto_now_add=True)
label = models.ForeignKey(MessageLabel, null=True, blank=True)
archived_by = models.ForeignKey(OrgStaff)
tags = TaggableManager()
I define awesome, legend, rockstar for the model person. There might few more be defined.
As is quite clear, I do not want the tags for person and message to overlap.
How should I achieve that? Thanks!
You can utilize the limit_choices_to feature on ForeignKeyFields and ManyToManyFields. Your models.py file might look like this:
class PersonArchive(models.Model):
tags_field = models.ManyToManyField(Tag, related_name="people_archives", limit_choices_to={'message_archives__isnull': True})
class MessageArchive(models.Model):
tags_field = models.ManyToManyField(Tag, related_name="message_archives", limit_choices_to={'people_archives__isnull': True})
You your case, as far as I understand, you want different base families of tag for the two different models.
Take in account I'm not an expert on taggit, so the solution I'm proposing can be a bit overcomplitated, but is the first that jump me in mind by looking at the source code.
You can achieve that by extending the TaggableRel class used by TaggableManager and add a condition to the limit_choices_to parameter:
Extend TaggableRel
class CustomTaggableRel(TaggableRel):
def __init__(self, field, model_name):
super(TaggableRel, self ).__init__(field)
self.limit_choices_to = {'content_type': model_name}
Than you extend TaggableManager in the following way:
class CustomTaggableManager(TaggableManager):
def __init__(self, model_name=None, verbose_name=_("Tags"),
help_text=_("A comma-separated list of tags."), through=None, blank=False):
super(TaggableManager, self ).__init__(verbose_name, help_text, through, blank)
self.rel = CustomTaggableRel(self, model_name)
Than you your models:
class PersonArchive(models.Model):
.
.
.
tags = CustomTaggableManager(model_name="PersonArchive")
This should do the trick, didn't try the solution and I write it down very fast, but this could drive you on the right path.
Just dealt with this myself. I decided to let my tags intermingle because I found a way to only filter tags for specific models. This will only filter tags for modelname. You can expand the filter as desired.
Tag.objects.filter(taggit_taggeditem_items__content_type__model='modelname')
I have a model that looks like this in my application:
class Member(models.Model):
name = models.CharField(max_length=200)
telephone_number = models.CharField(max_length=200)
email_address = models.CharField(max_length=200)
membership_type = models.CharField(max_length=1, choices=MEMBERSHIP_TYPES)
membership_number = models.CharField(max_length=200, primary_key=True)
def __unicode__(self):
return self.name
Reading up on forms for my model i see that i can replace the models stuff with forms and place it in my forms.py. However when for membership type i don't know how it is used in the forms class.
Hmmm... You might want to read on ModelForms.
Using the multiple choice field in the forms class.