I am developing a django application that has private section and public section. How can I develop such app with django? I have tried having Model Manager and also template tags but neither make a user's post private and also after posting they can make a post public or private by a Boolean Field.
the following is my Post Model:
from __future__ import unicode_literals
from django.conf import settings
from django.contrib.contenttypes.models import ContentType
from django.core.urlresolvers import reverse
from django.db import models
from django.db.models.signals import pre_save
from django.utils import timezone
from django.utils.safestring import mark_safe
from django.utils.text import slugify
from markdown_deux import markdown
from comments.models import Comment
from .utils import get_read_time
class PostManager(models.Manager):
def active(self, *args, **kwargs):
# Post.objects.all() = super(PostManager, self).all()
return super(
PostManager,
self).filter(draft=False).filter(publish__lte=timezone.now())
def public_post(self, *args, **kwargs):
return super(
PostManager,
self).filter(public=True)
def private_post(self, *args, **kwargs):
return super(
PostManager,
self).filter(public=False)
def upload_location(instance, filename):
return "%s/%s.%s" % (instance.id, instance.id, filename)
class Post(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL, default=1)
title = models.CharField(max_length=120)
slug = models.SlugField(unique=True, allow_unicode=True)
image = models.ImageField(
upload_to=upload_location,
null=True,
blank=True,
width_field="width_field",
height_field="height_field")
height_field = models.IntegerField(default=0)
width_field = models.IntegerField(default=0)
content = models.TextField()
draft = models.BooleanField(default=False)
publish = models.DateField(auto_now=False, auto_now_add=False)
read_time = models.IntegerField(
default=0) # models.TimeField(null=True, blank=True)
public = models.BooleanField(default=False)
private = models.BooleanField(default=True)
updated = models.DateTimeField(auto_now=True, auto_now_add=False)
timestamp = models.DateTimeField(auto_now=False, auto_now_add=True)
objects = PostManager()
def __unicode__(self):
return self.title
def __str__(self):
return self.title
def get_absolute_url(self):
return reverse("posts:detail", kwargs={"slug": self.slug})
class Meta:
ordering = ["-timestamp", "-updated"]
def get_markdown(self):
content = self.content
markdown_text = markdown(content)
return mark_safe(markdown_text)
def save(self,
force_insert=False,
force_update=False,
using=None,
update_fields=None):
from unidecode import unidecode
from django.template import defaultfilters
if not self.title == "":
self.slug = defaultfilters.slugify(unidecode(self.title))
super(Post, self).save()
@property
def comments(self):
instance = self
qs = Comment.objects.filter_by_instance(instance)
return qs
@property
def get_content_type(self):
instance = self
content_type = ContentType.objects.get_for_model(instance.__class__)
return content_type
@property
def is_public(self):
return self.public
@property
def is_private(self):
return self.private
def create_slug(instance, new_slug=None):
slug = slugify(instance.title)
if new_slug is not None:
slug = new_slug
qs = Post.objects.filter(slug=slug).order_by("-id")
exists = qs.exists()
if exists:
new_slug = "%s-%s" % (slug, qs.first().id)
return create_slug(instance, new_slug=new_slug)
return slug
def pre_save_post_receiver(sender, instance, *args, **kwargs):
if not instance.slug:enter code here
instance.slug = create_slug(instance)
if instance.content:
html_string = instance.get_markdown()
read_time_var = get_read_time(html_string)
instance.read_time = read_time_var
pre_save.connect(pre_save_post_receiver, sender=Post)
You're pulling all private posts, when what you really want is all private posts for one specific user.
What you should do is something like this:
class PostManager(models.Manager):
def active(self, *args, **kwargs):
# Post.objects.all() = super(PostManager, self).all()
return super(
PostManager,
self).filter(draft=False).filter(publish__lte=timezone.now())
def public_posts(self, *args, **kwargs):
return super(PostManager, self).filter(public=True)
# This sounds better plural, no?
def private_posts(self, *args, **kwargs):
user = kwargs.pop('user')
return super(PostManager, self).filter(public=False, user=user)
then elsewhere, you can pull private posts like so:
def some_view(request):
private_posts = Post.objects.private_posts(user=request.user)
Which should return all private posts where the user matches the one making the request.