Related
I will create a different author table using the user table available in django and I want to combine this custom table I created with the column in the post model. Thus, I will have both the author table and the post table with the posts shared by these authors separately. And also, I will make the user models that I will create in the future with the ready user table. but I am getting the error I mentioned.
When i add authors to admin panel I get this error. When I add 1 author, there is no problem, but when I add 2nd author, I get this error. How can I solve this, what are the alternative ways?
from django.db import models
from django.contrib.contenttypes.models import ContentType
from django.db import models
from django.urls import reverse
from .utils import get_read_time
from django.conf import settings
from django.utils import timezone
from markdown_deux import markdown
from django.utils.text import slugify
from django.contrib.auth.models import User
from django.db.models.signals import pre_save
from django.utils.safestring import mark_safe
class GENDER(models.TextChoices):
Erkek = "Erkek"
Kadın = "Kadın"
Diğer = "Diğer"
NONE = "Belirtmek İstemiyorum"
class Category_Choices(models.TextChoices):
BİLİNMEYENLER = '13İlinmeyenler'
KİŞİSEL_GELİŞİM = 'Kişisel Gelişim'
İLHAM_AL = 'İlham Al'
YATIRIM_HABERLERİ = 'Yatırım Haberleri'
GİRİŞİMCİLİK = 'Girişimcilik'
ENGLİSH_NEWS = 'English News'
BAŞARI_HİKAYELERİ = "Başarı Hikayeleri"
class Color_Choices(models.TextChoices):
INDIGO = 'indigo'
green = 'green'
yellow = 'yellow'
RED = 'red'
blue = 'blue'
gray = 'gray'
pink = "pink"
class Author(models.Model):
author = models.ForeignKey(User, on_delete = models.CASCADE)
firstName = models.CharField(max_length=80)
lastName = models.CharField(max_length=80)
email = models.EmailField(null=True,blank=True)
displayName = models.CharField(max_length=100)
gender = models.TextField(blank=False,choices=GENDER.choices)
avatar = models.ImageField(upload_to="avatar")
href = models.SlugField(unique=True,editable=False)
desc = models.TextField()
jobName = models.CharField(default="Yazar",max_length=30)
bgImage = models.ImageField(null=True, blank=True, upload_to="background")
def __str__(self):
return self.displayName
def get_slug(self):
href = slugify(self.displayName.replace("ı","i"))
unique = href
number = 1
while Author.objects.filter(slug=unique).exists():
unique = "{}-{}" .format(href,number)
number += 1
return unique
class Categories(models.Model):
name = models.CharField(max_length=50,choices=Category_Choices.choices,default=Category_Choices.BİLİNMEYENLER)
color = models.CharField(max_length=30,choices=Color_Choices.choices, default=Color_Choices.RED)
href = models.SlugField(unique=True,editable=False)
thumbnail = models.ImageField(upload_to="postpost",null=True,blank=True)
def __str__(self):
return self.name
def get_category_slug(self):
slug = slugify(self.name.replace("ı","i"))
unique = slug
number = 1
while Categories.objects.filter(slug=unique).exists():
unique = "{}-{}" .format(slug,number)
number += 1
return unique
def save(self, *args, **kwargs):
self.href = slugify(self.name)
super(Categories,self).save(*args, **kwargs)
def get_absolute_url(self):
return self.href
class Post(models.Model):
authorId = models.ManyToManyField(Author)
title = models.CharField(max_length=255)
desc = models.CharField(max_length=255)
categoryID = models.ForeignKey(Categories,on_delete=models.CASCADE,)
content = models.TextField(blank=False)
href = models.SlugField(unique=True,editable=False)
draft = models.BooleanField(default=True)
readingtime = models.IntegerField(default=0)
updated = models.DateTimeField()
date = models.DateTimeField(editable=False,null=True)
published = models.DateField(default=timezone.now)
featuredimage = models.ImageField(null=True, blank=True, upload_to='post')
class Meta:
ordering = ['-date', '-updated']
def __str__(self):
return self.title
def get_slug(self):
slug = slugify(self.title.replace("ı","i"))
unique = slug
number = 1
while Post.objects.filter(slug=unique).exists():
unique = "{}-{}" .format(slug,number)
number += 1
return unique
##property
#def comments(self):
# instance = self
# qs = Comment.objects.filter_by_instance(instance)
# return qs
def get_markdown(self):
content = self.content
markdown_text = markdown(content)
return mark_safe(markdown_text)
def pre_save_receiver(sender, instance, *args, **kwargs):
if not instance.href and instance.title:
instance.href = slugify(instance.title)
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_receiver, sender=Post)
and this error
IntegrityError at /adminpost/author/add/
UNIQUE constraint failed: post_author.href
Request Method: POST
Request URL: http://127.0.0.1:8000/adminpost/author/add/
Django Version: 3.2.8
Exception Type: IntegrityError
Exception Value:
UNIQUE constraint failed: post_author.href
It seems that you try to make a create with a title that already exists. Thus your href field isn't unique anymore.
Either also make the title field unique or you can add some random number identifier to your slug.
import uuid
def pre_save_receiver(sender, instance, *args, **kwargs):
if not instance.href and instance.title:
if not Post.objects.filter(href=slugify(instance.title)).exists():
instance.href = slugify(instance.title)
else:
instance.href = slugify(instance.title) + str(uuid.uuid4())[:8]
I have a model named Post, and want to save the full name of the admin automatically who created(or edited) that post.
I read about get_full_name() in django documentation, but I cannot understand how to call this method.
Here is my Post model
class Post(models.Model):
post_id = models.AutoField
postname = models.CharField(max_length=50)
description = models.CharField(max_length=1000)
location = models.CharField(max_length=30)
user = // I want to store the logged in admin full name here
Try the steps below.
Create a middleware that will store the context of the current user to a local thread. Add this middleware to the bottom of middlewares list in settings.
import threading
local = threading.local()
class BaseMiddleware(object):
def __init__(self, get_response):
self.get_response = get_response
def __call__(self, request):
local.user = request.user
response = self.get_response(request)
return response
Use local thread to get current user and store it in db white creating and updating post.
from .middleware import local
class Post(models.Model):
post_id = models.AutoField
postname = models.CharField(max_length=50)
description = models.CharField(max_length=1000)
location = models.CharField(max_length=30)
created_by = models.ForeignKey(
User,
on_delete=models.CASCADE,
related_name="%(class)s_created_by_user",
)
updated_by = models.ForeignKey(
User,
on_delete=models.CASCADE,
related_name="%(class)s_updated_by_user",
)
def save(self, *args, **kwargs):
if (
self.pk is None
and hasattr(local, "user")
and local.user.__class__ != AnonymousUser
):
self.created_by = local.user
elif (
self.pk
and hasattr(local, "user")
and local.user.__class__ != AnonymousUser
):
self.updated_by = local.user
return super().save(*args, **kwargs)
How to get user id from JWT token.
My JWT token has payload something like this:
{
"username": "Steve",
"is_admin": false,
"id": 1
}
How do I get access to user id?
I actually want to update certain fields in database as per the id, that are for a specific user.
Secondly after gaining the access how do I get update the fields?
models.py
class Profile(models.Model):
branch = models.CharField(max_length=20, null=True)
year = models.IntegerField(null=True)
image = models.ImageField(upload_to="accounts/images/", null=True, blank=True)
serializer.py
class ProfileSerializer(serializers.ModelSerializer):
class Meta:
model = Profile
fields = ('branch', 'year' ,'image',)
What will be the view to update these fields?
You should use the User object associated with the current request object. This assumes the cookie being present means that the user has a logged-in session when visiting the view in question,
def update_profile(request):
current_user = request.user
profile = Profile.objects.get(user=current_user.pk)
profile.update(field_a="value a", field_b="value b") # etc, example only
profile.save()
To make this possible, you also need to add the user relation as a OneToOne field within the Profile object:
from django.contrib.auth import User # assuming no customisation has been done to User model
# All your other imports and code
class Profile(models.Model):
branch = models.CharField(max_length=20, null=True)
year = models.IntegerField(null=True)
image = models.ImageField(upload_to="accounts/images/", null=True, blank=True)
user = models.OneToOneField(
User,
on_delete=models.CASCADE,
primary_key=False,
)
serializers.py
from django.contrib.auth import get_user_model
from rest_framework import serializers
class UserSerializer(serializers.ModelSerializer):
class Meta:
model = get_user_model()
exclude = ()
views.py
import base64
import json
from django.contrib.auth import get_user_model
from rest_framework.generics import RetrieveUpdateAPIView
class MyUserViewset(RetrieveUpdateAPIView):
queryset = get_user_model().objects.all()
serializer_class = MyUserSerializer
pagination_class = None
def get_object(self):
request = self.request
token = http_auth = request.META.get('HTTP_AUTHORIZATION', None)
token = token.replace("Token ", "")
user_json = json.loads(base64.b64decode(token.split(".")[1]))
user_id = user_json['id']
User = get_user_model()
user_obj = User.objects.get(id=user_id)
return user_obj
How long should this take to run?
query = Contact.objects.filter(contact_owner=batch.user, subscribed=True)
objs = [
Message(
recipient_number=e.mobile,
content=content,
sender=e.contact_owner,
billee=user,
sender_name=sender,
)
for e in query
Just this code nothing else (not saving to db I'm only running above i.e. create the objects). It takes 15 mins for 5000 messages objects to be created in the query. Is this right? Why is Django so slow?
This is the model it creates, again I'm not saving here. I think there ahs to be an issue in the model when an object is created, that or Django is just too slow for my needs.
Model message
from django.db import models
from django.contrib.contenttypes import generic
from django.utils.translation import ugettext as _
from django.conf import settings
from django.db.models.signals import post_save, pre_save
from django.dispatch import receiver
import uuidfield.fields
import picklefield
import jsonfield
if 'timezones' in settings.INSTALLED_APPS:
from timezones.utils import adjust_datetime_to_timezone
else:
def adjust_datetime_to_timezone(a, b, c):
return a
from gateway import Gateway
class MessageManager(models.Manager):
def get_matching_message(self, datadict):
for gateway in Gateway.objects.all():
try:
return Message.objects.get(
gateway_message_id=datadict.get(gateway.status_msg_id),
gateway=gateway,
)
except Message.DoesNotExist:
pass
def get_original_for_reply(self, datadict):
for gateway in Gateway.objects.all():
try:
return Message.objects.get(
uuid=datadict.get(gateway.uuid_keyword),
gateway=gateway
)
except Message.DoesNotExist:
pass
# This may have been a message sent from another phone, but
# there may be a reply-code that was added in.
return self.custom_reply_matcher(datadict)
def custom_reply_matcher(self, datadict):
# Designed to be overridden.
return None
def get_last_rate_for(self, recipient_number):
m = Message.objects.filter(recipient_number=recipient_number).exclude(
gateway_charge=None).order_by('-send_date')[0]
return m.gateway_charge / m.length
def get_message(self, gateway_message_id):
try:
return Message.objects.get(gateway_message_id=gateway_message_id,)
except Message.DoesNotExist:
pass
MESSAGE_STATUSES = (
('Unsent', 'Unsent'),
('Sent', 'Sent'),
('Delivered', 'Delivered'),
('Failed', 'Failed'),
)
class Message(models.Model):
"""
A Message.
We have a uuid, which is our reference. We also have a gateway_message_id,
which is their reference. This is required by some systems so we can
pass in a unique value that will allow us to match up replies to original
messages.
"""
content = models.TextField(help_text=_(u'The body of the message.'))
recipient_number = models.CharField(max_length=32,
help_text=_(u'The international number of the recipient'
', without the leading +'))
sender = models.ForeignKey('auth.User', related_name='sent_sms_messages')
sender_name = models.CharField(max_length=11)
send_date = models.DateTimeField(null=True, blank=True, editable=False)
delivery_date = models.DateTimeField(null=True, blank=True, editable=False,
help_text="The date the message was sent.")
uuid = uuidfield.fields.UUIDField(auto=True,
help_text=_(u'Used for associating replies.'))
status = models.CharField(max_length=16, choices=MESSAGE_STATUSES,
default="Unsent",
)
status_message = models.CharField(max_length=128, null=True, blank=True)
billed = models.BooleanField(default=False)
content_type = models.ForeignKey('contenttypes.ContentType')
object_id = models.PositiveIntegerField()
billee = generic.GenericForeignKey()
gateway = models.ForeignKey('sms.Gateway',
null=True, blank=True, editable=False)
gateway_message_id = models.CharField(max_length=128,
blank=True, null=True, editable=False)
reply_callback = picklefield.PickledObjectField(null=True, blank=True)
gateway_charge = models.DecimalField(max_digits=10, decimal_places=5,
null=True, blank=True)
charge = models.DecimalField(max_digits=10, decimal_places=5,
null=True, blank=True)
objects = MessageManager()
class Meta:
app_label = 'sms'
permissions = (
('view_message', 'Can view message'),
)
ordering = ('send_date',)
def send(self, gateway):
gateway.send(self)
#property
def length(self):
"""Unicode messages are limited to 70 chars/message segment."""
# try:
# return len(str(self.content)) / 160 + 1
# except UnicodeEncodeError:
# return len(self.content) / 70 + 1
return len(self.content) / 160 + 1
#property
def local_send_time(self):
# TODO: Get this from UserProfile?
if getattr(self.billee, 'timezone', None):
return adjust_datetime_to_timezone(
self.send_date,
settings.TIME_ZONE,
self.billee.timezone
)
return self.send_date
#property
def local_send_date(self):
return self.local_send_time.date()
def __unicode__(self):
return "[%s] Sent to %s by %s at %s [%i]" % (
self.status,
self.recipient_number,
self.sender,
self.send_date,
self.length
)
#receiver(pre_save, sender=Message)
def my_handler(sender, **kwargs):
instance = kwargs['instance']
if not instance.charge:
instance.charge = instance.length
# No need to save, as we're slipping the value in
# before we hit the database.
contact model
import os
import datetime
from uuid import uuid4
from datetime import date
from django.db import models
from django.core.urlresolvers import reverse
from django.contrib.auth.models import User
from django.utils.translation import ugettext as _
from django.utils import timezone
from django.db.models.signals import pre_delete
from django.dispatch.dispatcher import receiver
from adaptor.fields import *
from adaptor.model import CsvModel
def path_and_rename(path):
"""
Callable function for renaming the file being uploaded.
"""
def wrapper(instance, filename):
ext = filename.split('.')[-1]
# get filename
if instance.pk:
filename = '{}.{}'.format(instance.pk, ext)
else:
# set filename as random string
filename = '{}.{}'.format(uuid4().hex, ext)
# return the whole path to the file
return os.path.join(path, filename)
return wrapper
class GroupManager(models.Manager):
def for_user(self, user):
return self.get_query_set().filter(user=user, )
class Group(models.Model):
"""
Stores all groups.
"""
name = models.CharField(max_length=60)
modified = models.DateTimeField(null=True, auto_now=True, help_text="Shows when object was modified.")
created = models.DateTimeField(auto_now_add=True, help_text="Shows when object was created.")
#FK
user = models.ForeignKey(User, related_name="user")
objects = GroupManager()
def __unicode__(self):
return self.name
def get_absolute_url(self):
return reverse('contacts.views.group', args=[str(self.id)])
def get_delete_url(self):
return reverse('contacts.views.group_delete_confirm', args=[str(self.id)])
class ContactManager(models.Manager):
"""
Custom Manager for keyword.
"""
def unsorted_contacts(self, user):
"""
Manager that will list all records for a user where group is 'None'.
"""
return self.get_query_set().filter(contact_owner=user, group=None)
def for_user_and_group(self, user, group):
"""
Manager that will list all records for a user where group is 'group'.
"""
return self.get_query_set().filter(contact_owner=user, group=group)
def for_user(self, user):
"""
Manager that will list all records for a user they own.
"""
return self.get_query_set().filter(contact_owner=user)
class Contact(models.Model):
"""
Stores all contacts.
"""
first_name = models.CharField(max_length=60, blank=True)
last_name = models.CharField(max_length=60, blank=True)
company = models.CharField(max_length=100, blank=True)
mobile = models.CharField(max_length=15)
email = models.EmailField(max_length=100, blank=True)
subscribed = models.NullBooleanField(default=1, help_text="Shows if contact is unsubscribed to SMS/Email.")
modified = models.DateTimeField(null=True, auto_now=True, help_text="Shows when object was modified.")
created = models.DateTimeField(auto_now_add=True, help_text="Shows when object was created.")
objects = ContactManager()
#FK
group = models.ForeignKey(Group, related_name='contacts', blank=True, null=True)
contact_owner = models.ForeignKey(User)
def __unicode__(self):
return self.first_name
def full_name(self):
return "%s %s" % (self.first_name, self.last_name)
def get_delete_url(self):
return reverse('contacts.views.contact_delete', args=[str(self.id), str(self.group_id)])
def get_group_absolute_url(self):
return reverse('contacts.views.group', args=[str(self.group_id)])
#property
def user(self):
return self.contact_owner
#receiver(pre_delete, sender=Contact)
def contact_cleanup(sender, instance, **kwargs):
"""
Do a bit of tidying up when deleting a Contact.
Sent at the beginning of a model's delete() method and a queryset's delete() method.
"""
# Remove any FK's not done by cascade delete like generic relationships.
from unsubscribe.models import Unsubscribe
unsubscribe_list = Unsubscribe.objects.filter(object_id=instance.id, content_type__model='contact')
unsubscribe_list.delete()
class Upload(models.Model):
"""
Stores jobs and status uploads of file uploads for CSV import.
"""
filepath = models.FileField(upload_to=path_and_rename('uploadsCSV'),
help_text="It can take several minutes for contacts to appear.")
# Upload audit information
uploaded_by = models.ForeignKey(User)
date_uploaded = models.DateTimeField(auto_now_add=True)
# Processing audit information
PENDING, PROCESSED, FAILED = 'Pending', 'Processed', 'Failed'
STATUSES = (
(PENDING, _(PENDING)),
(PROCESSED, _(PROCESSED)),
(FAILED, _(FAILED)),
)
status = models.CharField(max_length=64, choices=STATUSES, default=PENDING)
processing_description = models.TextField(blank=True, null=True)
num_records = models.PositiveIntegerField()
num_columns = models.PositiveIntegerField()
date_start_processing = models.DateTimeField(null=True)
date_end_processing = models.DateTimeField(null=True)
#FKs
group = models.ForeignKey(Group)
def get_configurator_url(self):
return reverse('contacts.views.upload_configurator', args=[str(self.id)])
def process(self, cleaned_data):
self.date_start_processing = timezone.now()
try:
group_position = self.num_columns + 1
upload_id_position = self.num_columns + 1
# Try and import CSV
import_this(data=self.filepath, extra_fields=[
{'value': self.group_id, 'position': group_position},
{'value': self.uploaded_by.id, 'position': upload_id_position}], cleaned_data=cleaned_data)
self._mark_processed(self.num_records)
except Exception as e:
self._mark_failed(unicode(e))
def was_processing_successful(self):
return self.status == self.PROCESSED
def was_processing_successful(self):
return self.status == self.PROCESSED
def _mark_processed(self, num_records, description=None):
self.status = self.PROCESSED
self.date_end_processing = date.today()
self.num_records = num_records
self.processing_description = description
self.save()
def _mark_failed(self, description):
self.status = self.FAILED
self.processing_description = description
self.save()
def import_this(cleaned_data, *args, **kw):
# make custom ContactCSVModel
class ContactCSVModel(CsvModel):
for k, v in cleaned_data.items():
if not v == '':
# print("---------------------------------")
# print(str(v))
# print("---")
# print(k[3:])
# print("---------------------------------")
setattr(CsvModel, v, CharField(row_num=k[3:]))
group = DjangoModelField(Group, row_num="5")
contact_owner = DjangoModelField(User, row_num="6")
class Meta:
delimiter = ","
dbModel = Contact
update = {'keys': ["mobile", "group"]}
return ContactCSVModel.import_data(*args, **kw)
If you install Django debugtoolbar you could actually see the queries being fired, and the code responsible on firing them.
This slowness is mainly because django fires a new db query every time you do e.mobile and e.contact_owner, in the loop.
To prevent these queries, prefetch the data using select_related like below
query = Contact.objects.select_related('mobile', 'contact_owner').filter(contact_owner=batch.user, subscribed=True)
If your relations are many to many, then use prefetch_related rather than select_related.
I know in templates you can easily count comments with get_comment_count, but how can you get the same count as a method inside a class in models.py?
For example
class Blog( models.Model ) :
def comment_count( self ) :
return self.comment_set.count() # This line won't work.
title = ....
....
I want to have comment_count so that I can get a count the comments in the admin page.
EDIT: For your convenience, here is the models.py for django.contrib.comments
from django.contrib.auth.models import User
from django.contrib.comments.managers import CommentManager
from django.contrib.contenttypes import generic
from django.contrib.contenttypes.models import ContentType
from django.contrib.sites.models import Site
from django.db import models
from django.core import urlresolvers
from django.utils.translation import ugettext_lazy as _
from django.utils import timezone
from django.conf import settings
COMMENT_MAX_LENGTH = getattr(settings,'COMMENT_MAX_LENGTH',3000)
class BaseCommentAbstractModel(models.Model):
"""
An abstract base class that any custom comment models probably should
subclass.
"""
# Content-object field
content_type = models.ForeignKey(ContentType,
verbose_name=_('content type'),
related_name="content_type_set_for_%(class)s")
object_pk = models.TextField(_('object ID'))
content_object = generic.GenericForeignKey(ct_field="content_type", fk_field="object_pk")
# Metadata about the comment
site = models.ForeignKey(Site)
class Meta:
abstract = True
def get_content_object_url(self):
"""
Get a URL suitable for redirecting to the content object.
"""
return urlresolvers.reverse(
"comments-url-redirect",
args=(self.content_type_id, self.object_pk)
)
class Comment(BaseCommentAbstractModel):
"""
A user comment about some object.
"""
# Who posted this comment? If ``user`` is set then it was an authenticated
# user; otherwise at least user_name should have been set and the comment
# was posted by a non-authenticated user.
user = models.ForeignKey(User, verbose_name=_('user'),
blank=True, null=True, related_name="%(class)s_comments")
user_name = models.CharField(_("user's name"), max_length=50, blank=True)
user_email = models.EmailField(_("user's email address"), blank=True)
user_url = models.URLField(_("user's URL"), blank=True)
comment = models.TextField(_('comment'), max_length=COMMENT_MAX_LENGTH)
# Metadata about the comment
submit_date = models.DateTimeField(_('date/time submitted'), default=None)
ip_address = models.IPAddressField(_('IP address'), blank=True, null=True)
is_public = models.BooleanField(_('is public'), default=True,
help_text=_('Uncheck this box to make the comment effectively ' \
'disappear from the site.'))
is_removed = models.BooleanField(_('is removed'), default=False,
help_text=_('Check this box if the comment is inappropriate. ' \
'A "This comment has been removed" message will ' \
'be displayed instead.'))
# Manager
objects = CommentManager()
class Meta:
db_table = "django_comments"
ordering = ('submit_date',)
permissions = [("can_moderate", "Can moderate comments")]
verbose_name = _('comment')
verbose_name_plural = _('comments')
def __unicode__(self):
return "%s: %s..." % (self.name, self.comment[:50])
def save(self, *args, **kwargs):
if self.submit_date is None:
self.submit_date = timezone.now()
super(Comment, self).save(*args, **kwargs)
def _get_userinfo(self):
"""
Get a dictionary that pulls together information about the poster
safely for both authenticated and non-authenticated comments.
This dict will have ``name``, ``email``, and ``url`` fields.
"""
if not hasattr(self, "_userinfo"):
self._userinfo = {
"name" : self.user_name,
"email" : self.user_email,
"url" : self.user_url
}
if self.user_id:
u = self.user
if u.email:
self._userinfo["email"] = u.email
# If the user has a full name, use that for the user name.
# However, a given user_name overrides the raw user.username,
# so only use that if this comment has no associated name.
if u.get_full_name():
self._userinfo["name"] = self.user.get_full_name()
elif not self.user_name:
self._userinfo["name"] = u.username
return self._userinfo
userinfo = property(_get_userinfo, doc=_get_userinfo.__doc__)
def _get_name(self):
return self.userinfo["name"]
def _set_name(self, val):
if self.user_id:
raise AttributeError(_("This comment was posted by an authenticated "\
"user and thus the name is read-only."))
self.user_name = val
name = property(_get_name, _set_name, doc="The name of the user who posted this comment")
def _get_email(self):
return self.userinfo["email"]
def _set_email(self, val):
if self.user_id:
raise AttributeError(_("This comment was posted by an authenticated "\
"user and thus the email is read-only."))
self.user_email = val
email = property(_get_email, _set_email, doc="The email of the user who posted this comment")
def _get_url(self):
return self.userinfo["url"]
def _set_url(self, val):
self.user_url = val
url = property(_get_url, _set_url, doc="The URL given by the user who posted this comment")
def get_absolute_url(self, anchor_pattern="#c%(id)s"):
return self.get_content_object_url() + (anchor_pattern % self.__dict__)
def get_as_text(self):
"""
Return this comment as plain text. Useful for emails.
"""
d = {
'user': self.user or self.name,
'date': self.submit_date,
'comment': self.comment,
'domain': self.site.domain,
'url': self.get_absolute_url()
}
return _('Posted by %(user)s at %(date)s\n\n%(comment)s\n\nhttp://%(domain)s%(url)s') % d
class CommentFlag(models.Model):
"""
Records a flag on a comment. This is intentionally flexible; right now, a
flag could be:
* A "removal suggestion" -- where a user suggests a comment for (potential) removal.
* A "moderator deletion" -- used when a moderator deletes a comment.
You can (ab)use this model to add other flags, if needed. However, by
design users are only allowed to flag a comment with a given flag once;
if you want rating look elsewhere.
"""
user = models.ForeignKey(User, verbose_name=_('user'), related_name="comment_flags")
comment = models.ForeignKey(Comment, verbose_name=_('comment'), related_name="flags")
flag = models.CharField(_('flag'), max_length=30, db_index=True)
flag_date = models.DateTimeField(_('date'), default=None)
# Constants for flag types
SUGGEST_REMOVAL = "removal suggestion"
MODERATOR_DELETION = "moderator deletion"
MODERATOR_APPROVAL = "moderator approval"
class Meta:
db_table = 'django_comment_flags'
unique_together = [('user', 'comment', 'flag')]
verbose_name = _('comment flag')
verbose_name_plural = _('comment flags')
def __unicode__(self):
return "%s flag of comment ID %s by %s" % \
(self.flag, self.comment_id, self.user.username)
def save(self, *args, **kwargs):
if self.flag_date is None:
self.flag_date = timezone.now()
super(CommentFlag, self).save(*args, **kwargs)
Comments are related to your Models via generic relations so you can look up the comments for your object as you would any generic relation:
from django.conrtib.comments.models import Comment
from django.contrib.contenttypes.models import ContentType
class Blog( models.Model ) :
def comment_count(self) :
ct = ContentType.objects.get_for_model(Blog)
obj_pk = self.id
return Comment.objects.filter(content_type=ct,object_pk=obj_pk).count()