Here is my code for saving slug automatically. But it doesn't work and I don't know why! I can't be totally wrong. Help me to get out.
from django.db import models
from django.urls import reverse
from django.template.defaultfilters import slugify
class Article(models.Model):
title = models.CharField(max_length=50)
body = models.TextField()
slug = models.SlugField(null=False,unique=True)
def __str__(self):
return self.title
def get_absolute_url(self):
return reverse('article_detail', kwargs={'slug': self.slug})
def save(self, *args, **kwargs): # new
if not self.slug:
self.slug = slugify(self.title)
return super().save(*args, **kwargs)
But in django Admin panel I have to save slug manually But I want to save it automatically.
Help me to understand this. Thanks Good People.
exclude the slug field from Django Admin by creating a ModelAdmin class as below,
# admin.py
class ArticleAdmin(admin.ModelAdmin):
exclude = ('slug',)
admin.site.register(Article, ArticleAdmin)
So, set null=True and add blank=True.
slug = models.SlugField(null=True, blank=True, unique=True)
Related
signals.py
#receiver(user_logged_in, sender=User)
def when_user_logs_in(sender, request, **kwargs):
print('user_logs_signal is called')
LoggedInUser.objects.get_or_create(user=kwargs.get('user'))
#receiver(user_logged_out, sender=User)
def when_user_logs_out(sender, request, **kwargs):
print('user logs out signal iscalled')
LoggedInUser.objects.get_or_create(user=kwargs.get('user')).delete()
models.py
class LoggedInUser(models.Model):
user = models.OneToOneField(User, related_name='logged_in_user', on_delete =models.CASCADE, null=True, blank=True)
session_key = models.CharField(max_length=32, null=True, blank=True)
def __str__(self):
return self.user.username
apps.py
class AccountsConfig(AppConfig):
default_auto_field = "django.db.models.BigAutoField"
name = "accounts"
def ready(self):
import accounts.signals
I have done anything that i found to solve signals now working but it didnt solve i have even added "accounts.apps.AccountsConfig" in my settings.py but still it not firing i am currently logged_in and using jwt based authentication , needs help
I'm learning the Class-Based View and ModelForm of Django, and I feel so confused with those things.
I want to create a page where users can post articles.
My implementation is as following:
models.py
class Post(models.Model):
id = models.CharField(primary_key=True, null=False, max_length=20)
owner = models.ForeignKey(User, on_delete=models.CASCADE, null=False)
content = models.TextField()
count_like = models.IntegerField(default=0)
created_time = models.DateTimeField()
last_modified = models.DateTimeField()
def save(self, *args, **kwargs):
''' On save, update last_modified '''
if not self.id:
count = Post.objects.count()
self.id = "PO" + str(count)
self.created_time = timezone.now()
self.last_modified = timezone.now()
return super(Post, self).save(*args, **kwargs)
def get_absolute_url(self):
print("pk"*100, self.pk)
return reverse('post_detail', kwargs={'pk': self.pk})
forms.py
class PostForm(forms.ModelForm):
class Meta:
model = Post
fields = ['content']
def save(self):
return super().save(commit=False)
views.py
class PostCreateView(generic.CreateView):
model = Post
form_class = PostForm
template_name="post/create.jinja"
def form_valid(self, form):
self.object = form.save()
self.object.owner = self.request.user
self.object.save()
return HttpResponseRedirect(self.get_success_url())
urlpatterns
path('create/', PostCreateView.as_view(), name="post_create")
I checked and this works.
As you can see, the Post model has many attributes, but I just want users to fill 1 field content, the others would be automatically initiated. Is there any way to improve my implementation, because it's seperated into many places (model save() method, form save() method, valid_form() method).
One more question is what is self.object role? After assigned to a Post model instance, what would it be used for?
Please help me, if you don't understand what I say please ask in comment. Thanks ^^
Literaly like title say...check the picture. When i try to make new Post it says i made it but it wont show up on admin page nor in detail.html.
http://prntscr.com/n0pfrv
here is my code for post model
from django.db import models
from django.utils import timezone
from django.contrib.auth.models import User
from django.urls import reverse
class Post(models.Model):
title = models.CharField(max_length=100)
slug = models.SlugField(help_text="A short label, generally used in URLs.",default='', max_length=100)
image = models.ImageField(default='default.jpg', upload_to='profile_pics')
content = models.TextField()
date_posted = models.DateTimeField(default=timezone.now)
author = models.ForeignKey(User, on_delete=models.CASCADE)
class Meta:
ordering = ['-date_posted']
def save(self):
slug = self.title
def get_absolute_url(self):
return reverse('detail', kwargs={'slug':self.slug})
def __str__(self):
return self.title
admin.py
from django.contrib import admin
from .models import Post
class PostAdmin(admin.ModelAdmin):
list_display = ['title', 'slug', 'date_posted', 'author']
list_filter = ['title', 'date_posted']
prepopulated_fields = { 'slug': ('title',)}
admin.site.register(Post, PostAdmin)
views.py in app called blog were i have model Post also
from django.contrib import messages
from . models import Post
from django.core.mail import send_mail
from django.views.generic import DeleteView, ListView
def index_view(request):
return render(request, 'blog/index_view.html')
def blog_view(request):
context = {
'posts': Post.objects.all()
}
return render(request, 'blog/blog_view.html', context)
class PostDetailView(DeleteView):
model = Post
template_name = 'blog/detail.html'
context_object_name = 'post'
If you need any other of my code im gonna post it
You don't actually save the data in your save(self) method:
def save(self):
slug = self.title
super(Post, self).save(*args, **kwargs)
You should call the real save method as mentioned in the docs:
Overriding predefined model methods
I'm trying to use CreateView, here is some problem and I'm stacking it.
enter code here
First of all, i'm trying to create a post and dynamically fill user field who create post. It save the post but don't save the user:
Image from admin
#views.py
class PostCreateView(CreateView):
model = Post
template_name = 'blog/post_create.html'
fields = ('title', 'slug', 'body',)
def form_valid(self, form):
form.instance.blog__user = self.request.user
return super(PostCreateView,self).form_valid(form)
#models.py
The second one, i think main problem, i don't use get_absolute_url correctly and I get this problem:
No URL to redirect to.
But it good works for post_detail.
class Blog(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
slug = models.SlugField(max_length=50)
def __str__(self):
return self.user.username
def create_blog(sender, **kwargs):
if kwargs['created']:
user_blog = Blog.objects.create(user=kwargs['instance'], slug=kwargs['instance'])
post_save.connect(create_blog, sender=User)
class Post(models.Model):
blog = models.ForeignKey(Blog, on_delete=models.CASCADE)
slug = models.SlugField(max_length=50, db_index=True)
title = models.CharField(max_length=120, db_index=True)
body = models.TextField(blank=True, db_index=True)
pub_date = models.DateTimeField(auto_now_add=True)
def get_absolute_url(self):
return reverse('post_detail_url', kwargs={'slug': self.slug,
'username': self.blog})
#urls.py
urlpatterns = [
path('<username>/create/', PostCreateView.as_view(), name='post_create'),
path('<username>/<str:slug>/', PostDetailView.as_view(), name='post_detail_url'),
path('<username>/', PostListView.as_view(), name='post_list_url'),
path('<username>/<str:slug>/update/', PostUpdateView.as_view(), name='post_update'),
]
I am tried to define get_success_url and I get this: NoReverseMatch
Please help I am really lost in the clouds!
Try below code
class PostCreateView(CreateView):
model = Post
template_name = 'blog/post_create.html'
fields = ('title', 'slug', 'body', 'blog')
def get_success_url(self):
return self.post_instance.get_absolute_url()
def form_valid(self, form):
form.instance.blog.user = self.request.user
self.post_instance = form.instance
return super(PostCreateView,self).form_valid(form)
I have a couple of models named User, Book, Issue. Model Book has a field named remaining which holds the value of the number of available books.
what I want:
When there is zero book available, Issuing a book is closed.
models.py
from django.db import models
from datetime import date, timedelta, datetime
class Book(models.Model):
name = models.CharField(max_length=30)
author_name = models.CharField(max_length=30)
category = models.CharField(max_length=30)
remaining = models.IntegerField()
def __str__(self):
return self.name
class Issue(models.Model):
issue_id = models.CharField(max_length=10)
roll = models.ForeignKey(User, on_delete=models.CASCADE)
book_name = models.ForeignKey(Book, on_delete=models.CASCADE)
issue_date = models.DateField(auto_now=False, auto_now_add=True)
def save(self, *args, **kwargs):
if not self.pk:
super().save(*args, **kwargs)
if self.book_name.remaining > 0:
self.book_name.remaining -= 1
self.book_name.save()
elif self.book_name.remaining == 0:
print('hi')
else:
super().save(*args, **kwargs)
admin.py
from django.contrib import admin
from django.contrib.auth.models import Group
from .models import User, Book, Issue
class BookAdmin(admin.ModelAdmin):
list_display = ('name', 'author_name', 'remaining', 'category')
list_filter = ('category', 'author_name')
search_fields = ('name', 'author_name')
class IssueAdmin(admin.ModelAdmin):
list_display = ('issue_id', 'issue_date', 'return_date', 'fine',)
list_filter = ('issue_date',)
search_fields = ('issue_id',)
admin.site.register(Book, BookAdmin)
admin.site.register(Issue, IssueAdmin)
I want to Implement this in Admin Dashboard
Regards
On the clean function just check to see if the books are available.
And raise validation error if there are not any available.
def clean(self, *args, **kwargs):
from django.core.exceptions import ValidationError
super().clean()
if self.book_name.remaining < 1:
raise ValidationError("No books available")
else:
self.book_name.remaining -= 1
self.book_name.save()