Unit testing in Django for CreateView - python

I have a CreateView with which I create new blog posts, I want to test it in order to check if everything is ok but something is wrong with my test and I can't understand what exactly. it gives me 2 errors, for the first method I get this error:
Traceback (most recent call last):
File "C:\Users\Bularu Lilian\Desktop\EcoMon\blog\tests\test_views.py", line 73, in test_post_create_view_GET
self.assertEquals(response.status_code, 200)
AssertionError: 302 != 200
and for the second one is this error:
File "C:\Users\Bularu Lilian\Desktop\EcoMon\blog\tests\test_views.py", line 78, in test_post_create_view_POST_success
post = Post.objects.get(title=self.post['title'])
File "C:\Users\Bularu Lilian\Desktop\Environments\ecomon\lib\site-packages\django\db\models\manager.py", line 85, in manager_method
return getattr(self.get_queryset(), name)(*args, **kwargs)
File "C:\Users\Bularu Lilian\Desktop\Environments\ecomon\lib\site-packages\django\db\models\query.py", line 429, in get
raise self.model.DoesNotExist(
blog.models.Post.DoesNotExist: Post matching query does not exist.
This is my Test class:
class TestPostCreateViews(BaseTest):
def test_post_create_view_GET(self):
response = self.client.get(self.add_post_url)
self.assertEquals(response.status_code, 200)
self.assertTemplateUsed(response, 'blog/add_post.html')
def test_post_create_view_POST_success(self):
response = self.client.post(self.add_post_url, self.post, author=self.user, format='text/html')
post = Post.objects.get(title=self.post['title'])
self.assertEquals(response.status_code, 302)
self.assertEquals(post.title, 'test post')
my CreateView:
class PostCreateView(LoginRequiredMixin, IsSuperuserOrStaffMixin, CreateView):
template_name = 'blog/add_post.html'
form_class = PostCreateForm
def form_valid(self, form):
form.instance.author = self.request.user
return super().form_valid(form)
my url path:
path('new/post/', PostCreateView.as_view(), name='add-post'),
my form:
class PostCreateForm(forms.ModelForm):
title = forms.CharField(widget=forms.TextInput(), max_length=200)
content = forms.CharField(widget=forms.Textarea(attrs={'rows': 25, 'cols': 50}))
class Meta:
model = Post
exclude = ['author', 'slug', 'published_date', 'updated_date']
and my model:
class Post(models.Model):
class PostCategory(models.TextChoices):
FAMILY = 'FAMILY', _('Family')
BUSINESS = 'BUSINESS', _('Business')
MWRKETING = 'MARKETING', _('Marketing')
SPENDINGS = 'SPENDINGS', _('Spendings')
author = models.ForeignKey(User, on_delete=models.CASCADE)
title = models.CharField(_('Title'), max_length=200, unique=True)
content = models.TextField(_('Content'))
category = models.CharField(_('Category'), max_length=9, choices=PostCategory.choices, default=PostCategory.BUSINESS)
slug = models.SlugField(_('Slug'), max_length=200, blank=True, null=False, unique=True)
tags = TaggableManager(_('Tags'))
published_date = models.DateTimeField(_('Published Date/Time'), auto_now_add=True)
updated_date = models.DateTimeField(_('Updated Date/Time'), auto_now=True)
def __str__(self):
return self.title
def save(self, *args, **kwargs):
if not self.slug:
self.slug = slugify(self.title)
super().save(*args, **kwargs)
#property
def comments_count(self):
return self.comments.count()
def get_absolute_url(self):
return reverse('blog')
for any help I would be greatefull

Try to write it like this:
def test_post_create_view_POST_success(self):
data = {
'author': self.user,
'title': 'test_title',
'content': 'test_content',
'category': 'test_category',
'slug': 'test_slug',
'tags': None, # or create some tags and populate
}
response = self.client.post(self.add_post_url, data=data, follow=True) # make sure your url is correct too btw that could also be the issue
self.assertEquals(response.status_code, 200)
self.assertEquals(Post.objects.filter(title='test_title').count(), 1)

Related

Django2.1 : Queryset ModelChoice in a ModelForm then save two forms

I want the current logged in user to be able to create and save both forms. The second form has a ManyToManyField and ForeignKey relationships as you can see below.
Currently I have tried to queryset the current user from ChatGroupUser ModelForm.
With the current codes, as soon as I try to access the page, Django raise the error below:
__init__() missing 1 required positional argument: 'user'
it says that the error comes from line 88, which is:
form_user = ChatGroupUserForm()
Full Traceback
Traceback (most recent call last):
File "/Users/macadmin/Documents/Django_fun4/Groupixx/lib/python3.7/site-packages/django/core/handlers/exception.py", line 34, in inner
response = get_response(request)
File "/Users/macadmin/Documents/Django_fun4/Groupixx/lib/python3.7/site-packages/django/core/handlers/base.py", line 126, in _get_response
response = self.process_exception_by_middleware(e, request)
File "/Users/macadmin/Documents/Django_fun4/Groupixx/lib/python3.7/site-packages/django/core/handlers/base.py", line 124, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/Users/macadmin/Documents/Django_fun4/Groupixx/groupixx/core/views.py", line 88, in create_group
form_user = ChatGroupUserForm()
TypeError: __init__() missing 1 required positional argument: 'user'
models.py
class ChatGroup(models.Model):
name = models.CharField(max_length=100, blank=True, null=True)
group_admin = models.ForeignKey(User, on_delete=models.CASCADE, related_name='chat_group_admins')
is_active = models.BooleanField(default=True, null=True)
is_current = models.BooleanField(default=False, null=True)
class ChatGroupUser(models.Model):
user = models.ManyToManyField(User)
chat_group = models.ForeignKey(ChatGroup, on_delete=models.CASCADE, related_name='chat_group_users')
forms.py
from django.contrib.auth import get_user_model
User = get_user_model()
class ChatGroupForm(forms.ModelForm):
class Meta:
model = ChatGroup
fields = ['name',]
class ChatGroupUserForm(forms.ModelForm):
class Meta:
model = ChatGroupUser
fields = ['user']
def __init__(self, user, *args, **kwargs):
super(ChatGroupUserForm, self).__init__(*args, **kwargs)
self.fields['user'].queryset = User.objects.filter(user=user)
views.py
def create_group(request):
if request.method == 'POST':
form_group = ChatGroupForm(request.POST)
form_user = ChatGroupUserForm(request.POST)
if form_group.is_valid():
create_form = form_group.save(commit=False)
create_form.group_admin = request.user
create_form.save()
form_user.save(commit=False)
form_user.user = user
form_user.save()
return redirect('core:group_list')
else:
form_group = ChatGroupForm()
form_user = ChatGroupUserForm()
context = {
'form_group':form_group,
'form_user': form_user
}
return render(request, 'core/create-group.html', context)
I would appreciate any help, I am not sure why django is throwing an error and why i am not able to create and save both forms.
it is because your init function has parameter user,
while your view didn't pass the user.
here's how to fix it
in your view:
form_user = ChatGroupUserForm(user=request.user)
then in your form:
class ChatGroupUserForm(forms.ModelForm):
class Meta:
model = ChatGroupUser
fields = ['user']
def __init__(self, *args, **kwargs):
self.user = kwargs.pop('user')
super(ChatGroupUserForm, self).__init__(*args, **kwargs)
self.fields['user'].queryset = User.objects.filter(user=self.user)
hope it works :)

ValueError: cannot assign using Mock()

I'm learning how to use Mock for testing in django (2.0.6 <= it can make the difference) but I'm stuck following a tutorial.
Here my test_views.py:
User = get_user_model() #I use this in other tests, I hope it don't interfere
#patch('lists.views.NewListForm')
class NewListViewUnitTest(unittest.TestCase):
def setUp(self):
self.request = HttpRequest()
self.request.POST['text'] = 'new list item'
self.request.user = Mock()
def test_passes_POST_data_to_NewListForm(self, mockNewListForm):
print('self.request', self.request.user)
new_list2(self.request)
mockNewListForm.assert_called_once_with(data=self.request.POST)
[...]
And here my error on testing:
self.request <Mock name='mock()' id='80288792'> #print result
E
======================================================================
ERROR: test_passes_POST_data_to_NewListForm (lists.tests.test_views.NewListViewU
nitTest)
----------------------------------------------------------------------
Traceback (most recent call last):
File "d:\python\Lib\unittest\mock.py", line 1179, in patched
return func(*args, **keywargs)
File "D:\progetti\superlists\lists\tests\test_views.py", line 149, in test_pas
ses_POST_data_to_NewListForm
new_list2(self.request)
File "D:\progetti\superlists\lists\views.py", line 42, in new_list2
list_.owner = request.user
File "C:\Users\fabio\.virtualenvs\superlist\lib\site-packages\django\db\models
\fields\related_descriptors.py", line 197, in __set__
self.field.remote_field.model._meta.object_name,
ValueError: Cannot assign "<Mock name='mock()' id='80288792'>": "List.owner" must be a "User" instance.
So, it look like it don't recognize the self.request.user = Mock() like a User instance.
Note on the test_view:
1) the print command
2) the User = get_user_model() variable. get_user_model() comes from django.contrib.auth. I think it don't interfere.
I add some more code for completeness, ask for more if you need.
My views.py:
def new_list2(request):
form = NewListForm(data=request.POST)
if form.is_valid():
list_ = List()
if request.user.is_authenticated:
list_.owner = request.user
list_.save()
form.save(owner=request.user)
return redirect(list_)
return render(request, 'home.html', {'form': form})
My forms.py:
class ItemForm(forms.models.ModelForm):
class Meta:
model = Item
fields = ('text',)
widgets = {
'text': forms.fields.TextInput(attrs={
'placeholder': 'Enter a to-do item',
'class': 'form-control input-lg',
}),
}
error_messages = {
'text': {'required': EMPTY_ITEM_ERROR}
}
def save(self, for_list):
self.instance.list = for_list
return super().save()
class NewListForm(ItemForm):
def save(self, owner):
if owner.is_authenticated:
return List.create_new(first_item_text=self.cleaned_data['text'],
owner=owner)
else:
return List.create_new(first_item_text=self.cleaned_data['text'])
My models.py:
class List(models.Model):
owner = models.ForeignKey(settings.AUTH_USER_MODEL, blank=True, null=True,
on_delete=models.PROTECT)
def get_absolute_url(self):
return reverse('view_list', args=[self.id])
#staticmethod
def create_new(first_item_text, owner=None):
list_ = List.objects.create(owner=owner)
Item.objects.create(text=first_item_text, list=list_)
return list_
#property
def name(self):
return self.item_set.first().text
#def __str__(self):
# return self.item_set.first().text
class Item(models.Model):
text = models.TextField(default='')
list = models.ForeignKey(List, default=None, on_delete=models.PROTECT)
class Meta:
ordering = ('id',)
unique_together = ('list', 'text')
def __str__(self):
return self.text
Please, any help will be appreciated

Apply foreign key (Brand) into the User Brand object

I am having an issue with the following line: user_brand = UserBrand(user=user, brand=serializers), I keep getting the following error:
Traceback (most recent call last):
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/django/core/handlers/base.py", line 149, in get_response
response = self.process_exception_by_middleware(e, request)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/django/core/handlers/base.py", line 147, in get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/django/views/decorators/csrf.py", line 58, in wrapped_view
return view_func(*args, **kwargs)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/django/views/generic/base.py", line 68, in view
return self.dispatch(request, *args, **kwargs)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/rest_framework/views.py", line 466, in dispatch
response = self.handle_exception(exc)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/rest_framework/views.py", line 463, in dispatch
response = handler(request, *args, **kwargs)
File "/Users/jeansymolanza/projects/adsoma-api/api/views.py", line 137, in post
return self.create(request, *args, **kwargs)
File "/Users/jeansymolanza/projects/adsoma-api/api/views.py", line 154, in create
user_brand = UserBrand(user=user, brand=serializers)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/django/db/models/base.py", line 439, in __init__
setattr(self, field.name, rel_obj)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/django/db/models/fields/related_descriptors.py", line 207, in __set__
self.field.remote_field.model._meta.object_name,
ValueError: Cannot assign "<module 'rest_framework.serializers' from '/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/rest_framework/serializers.py'>": "UserBrand.brand" must be a "Brand" instance.
All I want to do is apply the foreign key (Brand) into the User Brand object.
views.py
class BrandSignup(generics.CreateAPIView):
"""
Brand signup
HTTP POST
"""
queryset = Brand.objects.all()
serializer_class = BrandSignupSerializer
def post(self, request, *args, **kwargs):
return self.create(request, *args, **kwargs)
def create(self, request, *args, **kwargs):
if User.objects.filter(email=request.data['email']).exists():
response_details = {
'data': "",
'message': "This email account is already in use. Please try using another one.",
'code': "400",
'status': HTTP_400_BAD_REQUEST
}
return Response(response_details, status=response_details['status'])
else:
serializer = self.get_serializer(data=request.data)
if serializer.is_valid(raise_exception=True):
serializer.save()
user = User(email=request.data['email'], password=request.data['password'],
account_type=request.data['account_type'])
user.save()
user_brand = UserBrand(user=user, brand=serializer)
user_brand.save()
response_details = {
'data': request.data,
'message': "Account created successfully.",
'code': "201",
'status': HTTP_201_CREATED
}
else:
response_details = {
'data': serializer.errors,
'message': "Your account cannot be created at this moment in time. Please try again later.",
'code': "400",
'status': HTTP_400_BAD_REQUEST
}
return Response(response_details, status=response_details['status'])
models.py
class Brand(models.Model):
"""
Brand model
"""
id = models.UUIDField(primary_key=True, default=uuid4, editable=False)
name = models.CharField(max_length=255, null=True, default=None)
brand = models.CharField(max_length=255, null=True, default=None)
phone = models.CharField(max_length=255, null=True, default=None)
website = models.CharField(max_length=255, null=True, default=None)
class Meta:
verbose_name_plural = "Brands"
def __str__(self):
return "%s" % self.brand
class UserBrand(models.Model):
"""
User brand model
"""
id = models.UUIDField(primary_key=True, default=uuid4, editable=False)
user = models.ForeignKey(User, null=False, on_delete=models.CASCADE)
brand = models.ForeignKey(Brand, null=False, on_delete=models.CASCADE)
class Meta:
verbose_name_plural = "User Brands"
def __str__(self):
return "%s - %s" % (self.user, self.brand)
You're trying to pass a BrandSignupSerializer object to the UserBrand constructor as the brand... You need a Brand object instead. You should be able to fix this by replacing your line with
user_brand = UserBrand(user=user, brand=serializer.instance)

Django Sitemap -- 'str' object has no attribute 'get_absolute_url' Error

I'm getting the 'str' object has no attribute 'get_absolute_url' error on my django project on my sitemap page. Any help is appreciated.
Here is my traceback:
Traceback:
File "C:\Users\crstu\AppData\Local\Programs\Python\Python36-32\lib\site-packages\django\core\handlers\exception.py" in inner
35. response = get_response(request)
File "C:\Users\crstu\AppData\Local\Programs\Python\Python36-32\lib\site-packages\django\core\handlers\base.py" in _get_response
128. response = self.process_exception_by_middleware(e, request)
File "C:\Users\crstu\AppData\Local\Programs\Python\Python36-32\lib\site-packages\django\core\handlers\base.py" in _get_response
126. response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "C:\Users\crstu\AppData\Local\Programs\Python\Python36-32\lib\site-packages\django\contrib\sitemaps\views.py" in inner
16. response = func(request, *args, **kwargs)
File "C:\Users\crstu\AppData\Local\Programs\Python\Python36-32\lib\site-packages\django\contrib\sitemaps\views.py" in sitemap
71. protocol=req_protocol))
File "C:\Users\crstu\AppData\Local\Programs\Python\Python36-32\lib\site-packages\django\contrib\sitemaps\__init__.py" in get_urls
111. urls = self._urls(page, protocol, domain)
File "C:\Users\crstu\AppData\Local\Programs\Python\Python36-32\lib\site-packages\django\contrib\sitemaps\__init__.py" in _urls
120. loc = "%s://%s%s" % (protocol, domain, self.__get('location', item))
File "C:\Users\crstu\AppData\Local\Programs\Python\Python36-32\lib\site-packages\django\contrib\sitemaps\__init__.py" in __get
68. return attr(obj)
File "C:\Users\crstu\AppData\Local\Programs\Python\Python36-32\lib\site-packages\django\contrib\sitemaps\__init__.py" in location
75. return obj.get_absolute_url()
Exception Type: AttributeError at /sitemap.xml
Exception Value: 'str' object has no attribute 'get_absolute_url'
my sitemaps.py file
from django.contrib import sitemaps
from django.contrib.sitemaps import Sitemap
from django.urls import reverse
from deals.models import Deal
from blog.models import Post
class StaticViewSitemap(sitemaps.Sitemap):
priority = 1.0
changefreq = 'daily'
def items(self):
return ['about', 'contact', 'disclosure', 'terms', 'privacy', 'deals:deals', 'blog:blog']
class BlogSitemap(Sitemap):
changfreq = "daily"
priority = 1.0
location ='/blog'
def items(self):
return Post.objects.filter(status='Published')
def lastmod(self, obj):
return obj.created
class DealSitemap(Sitemap):
changfreq = "daily"
priority = 1.0
def items(self):
return Deal.objects.all()
def lastmod(self, obj):
return obj.date_added
and my two relevant models (Deal and Post) where i created a get_absolute_url methods since it had been generating an error on the sitemap prior:
class Deal(models.Model):
title = models.CharField(max_length=200)
slug = models.SlugField(max_length=140, unique=True)
description = RichTextUploadingField(default='')
retailer = models.ForeignKey(Retailer, on_delete=models.CASCADE)
image = VersatileImageField('deal image',
upload_to=deal_upload_path,
null=True,
blank=True)
link = models.URLField(max_length=2000, default='')
category = models.ForeignKey(Category, on_delete=models.CASCADE)
date_added = models.DateField(default=timezone.now)
date_expires = models.DateField(default=timezone.now)
price = models.CharField(max_length=140)
secondary_price = models.CharField(max_length=140, default='')
likes_total = models.IntegerField(default=1)
expired = models.BooleanField(default=False)
def __str__(self):
return "#{} ({})".format(self.title, self.retailer)
def _get_unique_slug(self):
slug = slugify(self.title)
unique_slug = slug
num = 1
while Deal.objects.filter(slug=unique_slug).exists():
unique_slug = '{}-{}'.format(slug, num)
num += 1
return unique_slug
def save(self, *args, **kwargs):
if not self.slug:
self.slug = self._get_unique_slug()
super().save()
def get_label(self):
if self.date_added > datetime.date.today() - datetime.timedelta(days=4):
return "<span class='"'notify-badge'"'>new</span>"
else:
return ''
def get_absolute_url(self):
return reverse('deals:deal_detail', kwargs={'slug': self.slug})
class Post(models.Model):
STATUS_CHOICES = (
('Published', 'Published'),
('Draft', 'Draft'),
)
title = models.CharField(max_length=100, unique=True)
body = RichTextUploadingField()
category = models.ForeignKey(BlogCategory, on_delete=models.CASCADE)
seo_title = models.CharField(max_length=60, blank=True, null=True)
seo_description = models.CharField(max_length=165, blank=True, null=True)
slug = models.SlugField(max_length=200, unique=True)
image = VersatileImageField('blog image',
upload_to='media/blog_images',
null=True,
blank=True)
created = models.DateTimeField(db_index=True, auto_now_add=True)
updated = models.DateTimeField(auto_now=True)
status = models.CharField(max_length=10, default='Draft', choices=STATUS_CHOICES)
def get_absolute_url(self):
return reverse('blog:blog_post', kwargs={'slug': self.slug})
def save(self, *args, **kwargs):
self.slug = slugify(self.title)
super(Post, self).save(*args, **kwargs)
def __str__(self):
return self.title
and my urls.py file with relevant info
from django.contrib.sitemaps.views import sitemap
sitemaps = {
'static': StaticViewSitemap,
'blog': BlogSitemap,
'deals': DealSitemap
}
path('sitemap.xml', sitemap,
{'sitemaps': sitemaps},
name='django.contrib.sitemaps.views.sitemap'),
You haven't followed the example properly for the StaticViewSitemap. As the docs say, the elements returned from items() are passed to the location() method; since the items would normally be model instances, the default implementation of this method is to call the get_absolute_url() method of each instance. In your case you are passing URL names, so you need to redefine location() appropriately - again as the example does.
def location(self, item):
return reverse(item)
It's the location() function who request for get_absolute_url() method : here. If you are absolutly sur that your string is already an absolute path you can simply override it in your class by:
def location(self, item) :
return item
This will return your already setup absolut path.

Django-Taggit saving tags from a model field

I am building a post editor for my website. One of the fields I can edit is for tags. However when I save the post everything updates correctly and no errors are thrown but any changes I made to the tags field are not saved.
# Views.py
class EditPostView(UpdateView):
form_class = EditPostForm
model = Post
template_name = 'myapp/editpost.html'
def get(self, request, pk):
if (not request.user.is_superuser):
return HttpResponseForbidden()
post = Post.objects.get(id=pk)
if (post is None):
return HttpResponseNotFound()
form = self.form_class(instance=post)
return render(request, self.template_name, {'form': form, 'post': post})
def post(self, request, pk):
if (not request.user.is_superuser):
return HttpResponseForbidden()
post = Post.objects.get(id=pk)
if (post is None):
return HttpResponseNotFound()
form = self.form_class(request.POST, instance=post)
if (form.is_valid()):
post.title = form.cleaned_data['title']
post.content_type = form.cleaned_data['content_type']
post.screenshot = form.cleaned_data['screenshot']
post.tags = form.cleaned_data['tags']
post.body = form.cleaned_data['body']
post.nsfw = form.cleaned_data['nsfw']
post.allow_comments = form.cleaned_data['allow_comments']
post.display_edited = form.cleaned_data['display_edited']
post.files = form.cleaned_data['files']
post.date_edited = datetime.now()
post.save()
return redirect('/posts/' + str(post.id))
else:
return HttpResponseNotFound()
return HttpResponseNotFound()
#Forms.py
class PostForm(forms.ModelForm):
class Meta:
model = Post
fields = ['title', 'content_type', 'screenshot', 'body', 'tags', 'nsfw', 'allow_comments', 'files']
widgets = {
'screenshot': forms.TextInput(attrs={'placeholder': 'URL...'}),
'tags': TagWidget(),
}
labels = {
'files': 'Attachments',
}
# Models.py
class Post(models.Model):
title = models.CharField(max_length=256)
disclaimer = models.CharField(max_length=256, blank=True)
BLOGS = 'blogs'
APPLICATIONS = 'applications'
GAMES = 'games'
WEBSITES = 'websites'
GALLERY = 'gallery'
PRIMARY_CHOICES = (
(BLOGS, 'Blogs'),
(APPLICATIONS, 'Applications'),
(GAMES, 'Games'),
(WEBSITES, 'Websites'),
)
content_type = models.CharField(max_length=256, choices=PRIMARY_CHOICES, default=BLOGS)
screenshot = models.CharField(max_length=256, blank=True)
tags = TaggableManager()
body = RichTextField()
date_posted = models.DateTimeField(default=datetime.now)
date_edited = models.DateTimeField(blank=True, null=True)
visible = models.BooleanField(default=True)
nsfw = models.BooleanField()
display_edited = models.BooleanField(default=False)
allow_comments = models.BooleanField(default=True)
files = models.ManyToManyField(File, blank=True)
def __str__(self):
if (self.visible == False):
return '(Hidden) ' + self.title + ' in ' + self.content_type
return self.title + ' in ' + self.content_type
You're doing a lot of unnecessary work here. You're not leveraging the power of the UpdateView. This is all you should need. It will call form.save() and everything for you
from django.http import HttpResponseForbidden
from django.shortcuts import get_object_or_404
from django.views.generic.edit import UpdateView
class EditPostView(UpdateView):
form_class = EditPostForm
model = Post
template_name = 'myapp/editpost.html'
def dispatch(self, *args, **kwargs):
if not self.request.user.is_superuser:
return HttpResponseForbidden()
return super(EditPostView, self).dispatch(*args, **kwargs)
def get_object(self, queryset=None):
return get_object_or_404(Post, id=self.kwargs['id'])
def get_success_url(self):
return '/posts/{0}'.format(self.object.id)
Edit: bonus points if you get rid of get_success_url and add a get_absolute_url method to the Post model.
class Post(models.Model):
...
def save(self, *args, **kwargs):
self.date_edited = datetime.now()
super(Post, self).save(*args, **kwargs)
def get_absolute_url(self):
return '/posts/{0}'.format(self.id)

Categories

Resources