I tried to add search fields in Django using python. Followings are the codes that I have used.
# admin.py file
from django.db import models
from blog.models import Blog
from django.contrib import admin
admin.site.register(Blog)
class Blog(models.Model):
title = models.CharField(max_length=60)
body = models.TextField()
created = models.DateTimeField("Date Created")
updated = models.DateTimeField("Date Updated")
def __unicode__(self):
return self.title
class Comment(models.Model):
body = models.TextField()
author = models.CharField(max_length=60)
created = models.DateTimeField("Date Created")
updated = models.DateTimeField("Date Updated")
post = models.ForeignKey(Blog)
def __unicode__(self):
return self.body
class CommentInline(admin.TabularInline):
model = Comment
class BlogAdmin(admin.ModelAdmin):
list_display = ('title','created', 'updated')
search_fields = ['title','body']
list_filter = ('Date Created','Date Updated')
inlines = [CommentInline]
class CommentAdmin(admin.ModelAdmin):
list_display = ('post','author','body_first_60','created','updated')
list_filter = ('Date Created','Date Updated')
I tried to add a search_fields for title and body by using Following code.
class BlogAdmin(admin.ModelAdmin):
. . .
search_fields = ('title','body')
. . .
When I run this I can't see any search box. Why is that ? I want your help. I'm just a beginner.
Thanks!
The search fields should be a list, not a tuple.
class BlogAdmin(admin.ModelAdmin):
. . .
search_fields = ['title','body']
. . .
Then make sure that you associate this admin object with the model.
admin.site.register(Blog, BlogAdmin)
EDIT:
It's hard to tell from above, but you should consider just importing the models from models.py instead of redefining them in your admin.py file. Again, it looks like that's what you're doing above.
admin.py:
from django.db import models
from blog.models import Blog
from django.contrib import admin
class CommentInline(admin.TabularInline):
model = Comment
class BlogAdmin(admin.ModelAdmin):
list_display = ('title','created','updated',)
search_fields = ['title','body',]
list_filter = ('Date Created','Date Updated',)
inlines = [CommentInline,]
class CommentAdmin(admin.ModelAdmin):
list_display = ('post','author','body_first_60','created','updated',)
list_filter = ('Date Created','Date Updated',)
admin.site.register(Blog, BlogAdmin)
models.py
from django.db import models
class Blog(models.Model):
title = models.CharField(max_length=60)
body = models.TextField()
created = models.DateTimeField("Date Created")
updated = models.DateTimeField("Date Updated")
def __unicode__(self):
return self.title
class Comment(models.Model):
body = models.TextField()
author = models.CharField(max_length=60)
created = models.DateTimeField("Date Created")
updated = models.DateTimeField("Date Updated")
post = models.ForeignKey(Blog)
def __unicode__(self):
return self.body
You should register your site at the bottom of the site rather than at the top.
Please try admin.site.register(Blog, BlogAdmin) at the bottom of the page. I hope that will solve your question
Related
I'm trying to code a blog with django but I want to add a placeholder to my form when creating or editing an article. So I had the forms.py because before that I wasn't using a form from this file because I only needed the models.py file. I fount a way to do what I wanted and so add my placeholder into my input from my forms. But one problem, when I updated my website and went to my pages to see the changed an error appeared.
So I tried to fix the problem by looking on the web and I saw a lot of people having approximately the same problem but the answers were that I had to add a get_queryset definition in my views in views.py for the specific forms. I didn't find what I have to set in the definition of the get_queryset and not very understood where I have to put these definitions. I would be very grateful if you can help me.
Here's my code :
My views in view.py :
class BlogHome(ListView):
model = BlogPost
context_object_name = "posts"
def get_queryset(self):
queryset = super().get_queryset()
if self.request.user.is_authenticated:
return queryset
else:
return queryset.filter(published=True)
#method_decorator(login_required, name='dispatch')
class BlogPostCreate(CreateView):
form_name = UpdatePostForm
class BlogPostEdit(UpdateView):
form_name = CreatePostForm
My urls.py :
urlpatterns = [
path('create/', BlogPostCreate.as_view(), name="create"),
path('edit/<str:slug>/', BlogPostEdit.as_view(), name="edit"),
My forms.py :
from django import forms
from posts.models import BlogPost
class UpdatePostForm(forms.Form):
model = BlogPost
template_name = 'posts/blogpost_edit.html'
fields = [
'title',
'slug',
'content',
'published',
'author',
'created_on'
]
class Meta:
title = forms.CharField(
widget = forms.TextInput(attrs={'placeholder' : 'Enter the title of the article'}),
),
slug = forms.CharField(
widget = forms.TextInput(attrs={'placeholder' : 'Enter the title of the article'}),
),
content = forms.CharField(
widget = forms.TextInput(attrs={'placeholder' : 'Enter the title of the article'}),
),
created_on = forms.CharField(
widget = forms.TextInput(attrs={'placeholder' : 'Enter the date of creation'}),
),
class CreatePostForm(forms.Form):
model = BlogPost
template_name = 'posts/blogpost_create.html'
fields = [
'title',
'slug',
'content',
'published',
'author',
'created_on'
]
class Meta:
title = forms.CharField(
widget = forms.TextInput(attrs={'placeholder' : 'Enter the title of the article'}),
),
slug = forms.CharField(
widget = forms.TextInput(attrs={'placeholder' : 'Enter the title of the article'}),
),
content = forms.CharField(
widget = forms.TextInput(attrs={'placeholder' : 'Enter the title of the article'}),
),
created_on = forms.CharField(
widget = forms.TextInput(attrs={'placeholder' : 'Enter the date of creation'}),
),
My models.py :
from django.contrib .auth import get_user_model
from django.template.defaultfilters import slugify
from django.db import models
from django import forms
from django.urls import reverse
User = get_user_model()
class BlogPost(models.Model):
title = models.CharField(max_length=255, unique=True, verbose_name="Titre")
slug = models.SlugField(max_length=255, unique=True, blank=True)
author = models.ForeignKey(User, on_delete=models.SET_NULL, null=True, blank=True)
last_updated = models.DateTimeField(auto_now=True)
created_on = models.DateField(blank=True, null=True)
published = models.BooleanField(default=False, verbose_name="Publié")
content = models.TextField(blank=True, verbose_name="Contenu")
thumbnail = models.ImageField(blank=True, upload_to='blog')
class Meta:
ordering = ['-created_on']
verbose_name = "Article"
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 author_or_default(self):
return self.author.username if self.author else "L'auteur inconnu"
def get_absolute_url(self):
return reverse('posts:home')
class BlogPostCreate(CreateView):
form_class = UpdatePostForm
template_name = 'update_post.html'
success_url = 'success'
OR
class BlogPostCreate(CreateView):
model = UpdatePost
Try the above. Please remove #method_decorator(login_required, name='dispatch') from this class view because its a class view not a method.
Your form should be a model for I expect.
class CreatePostForm(forms.ModelForm):
I am updating my answer as per your last comment. Check this for django modelForm. You need to add a meta in your form:
class CreatePostForm(forms.ModelForm):
class Meta:
model = User
fields = ['...', ....]
i want to hide a specific line of my Django Admin Model by permission or Group
My models.py
class Post(models.Model):
title = models.CharField(max_length=128)
slug = AutoSlugField(populate_from='title')
category = models.CharField(max_length=64, choices=CATEGORY_CHOICES, default='actus')
is_verified = models.BooleanField(default=False)
content = RichTextField(blank=True, null=True)
author = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
thumbnail = models.ImageField(upload_to='media/thumbs', blank=True, null=True, default="media/thumbs/default.jpg")
date = models.DateTimeField(auto_now_add=True, blank=True)
def __str__(self):
return self.title
def get_absolute_url(self):
return reverse("post", kwargs={"slug": self.slug, "category": self.category})
My Model admin
from django.contrib import admin
from django.db import models
from django.db.migrations.graph import Node
from django.utils.regex_helper import Group
from .....models import Post
class PostAdmin(admin.ModelAdmin):
list_display = ('title', 'author', 'date', 'is_verified')
list_filter = ('date', 'author', 'is_verified')
admin.site.site_header = 'Staff Dashboard'
admin.site.register(Post, PostAdmin)
My django admin page
Django admin page
If someone has an idea
You can define two ModelForms: one with the is_verified option, and one without, so:
# app_name/forms.py
from django import forms
from app_name.models import Post
class NormalUserPostForm(forms.ModelForm):
class Meta:
model = Post
exclude = ['is_verified']
class AdminUserPostForm(forms.ModelForm):
class Meta:
model = Post
fields = '__all__'
then we can override the get_form method of the ModelAdmin:
# app_name/admin.py
from app_name.forms import NormalUserPostForm, AdminUserPostForm
class PostAdmin(admin.ModelAdmin):
list_display = ('title', 'author', 'date', 'is_verified')
list_filter = ('date', 'author', 'is_verified')
form = NormalUserPostForm
def get_form(self, request, obj=None, **kwargs):
if request.user.is_superuser:
kwargs['form'] = AdminUserPostForm
return super().get_form(request, obj, **kwargs)
admin.site.site_header = 'Staff Dashboard'
admin.site.register(Post, PostAdmin)
You can change the condition to request.user.has_perm('some_permission') to check for a certain permission instead.
this is my setting for translations in the models.py file, django-parler 2.0.1 won't show fields for Products in the admin site after I had synch migrations. I am currently using Django 3.0.3.
from django.db import models
from django.urls import reverse
from parler.models import TranslatableModel, TranslatedFields
class Category(TranslatableModel):
translations = TranslatedFields(
name = models.CharField(max_length=200,
db_index=True),
slug = models.SlugField(max_length=200,
db_index=True,
unique=True)
)
class Meta:
# ordering = ('name',)
verbose_name = 'category'
verbose_name_plural = 'categories'
def __str__(self):
return self.name
def get_absolute_url(self):
return reverse('shop:product_list_by_category',
args=[self.slug])
class Product(TranslatableModel):
translations = TranslatedFields(
name = models.CharField(max_length=200, db_index=True),
slug = models.SlugField(max_length=200, db_index=True),
description = models.TextField(blank=True)
)
category = models.ForeignKey(Category,
related_name='products',
on_delete=models.CASCADE)
image = models.ImageField(upload_to='products/%Y/%m/%d',
blank=True)
price = models.DecimalField(max_digits=10, decimal_places=2)
available = models.BooleanField(default=True)
created = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)
#class Meta:
# ordering = ('name',)
# index_together = (('id', 'slug'),)
def __str__(self):
return self.name
def get_absolute_url(self):
return reverse('shop:product_detail',
args=[self.id, self.slug])
I have registered the model in the admin.py file but it won't show the fields for product description and price all I get is the translated tab.
from django.contrib import admin
from .models import Category, Product
from parler.admin import TranslatableAdmin
#admin.register(Category)
class CategoryAdmin(TranslatableAdmin):
list_display = ['name', 'slug']
def get_prepopulated_fields(self, request, obj=None):
return {'slug': ('name',)}
#admin.register(Product)
class ProductAdmin(TranslatableAdmin):
list_display = ['name', 'slug', 'price',
'available', 'created', 'updated']
list_filter = ['available', 'created', 'updated']
list_editable = ['price', 'available']
def get_prepopulated_fields(self, request, obj=None):
return {'slug': ('name',)}
I wonder what am doing wrong that I am getting this and I wonder if there's a better way to make translate configurations with Django-parler 2.0.1. any suggestions is welcomed!!
Apparently, I was able to fix the problem by first deleting all migrations and I also had to trash my database and switch to PostgreSQL and after that, I reapplied migrations and it worked. All fields are now visible in the admin site now yippee! but be mindful to make a backup of your database because everything will be deleted..
I am still not satisfied with django foreignkey relationship.
below are two classess .
from django.db import models
from django.utils.text import slugify
from django_countries.fields import CountryField
from django.conf import settings
# Create your models here.
class PhotoGallery(models.Model):
title = models.CharField(max_length=255,unique=True)
picture_choices =
models.CharField(max_length=255,choices=PICTURE_CHOICES,default=NTR)
description = models.TextField(default='')
user = models.ForeignKey(settings.AUTH_USER_MODEL,
on_delete=models.CASCADE,related_name='image_uploader')
date_posted = models.DateTimeField(auto_now=True)
views = models.PositiveIntegerField()
likes = models.PositiveIntegerField()
country = CountryField(blank_label='(select country)')
slug = models.SlugField(allow_unicode=True,unique=True)
def __str__(self):
return self.title
from django.contrib import admin
from gallery.models import PhotoGallery
class PhotoGalleryAdmin(admin.ModelAdmin):
prepopulated_fields = {'slug': ('title',)}
And below is class Imagesmodel that has a foreignkey .Calling the PhotoGallery class from class Imagesmodel is not a problem .MY big problem is doing the reverse
class ImagesModel(models.Model):
gala_obj =
models.ForeignKey(PhotoGallery,
related_name='picture_gallery',on_delete=models.CASCADE)
post_image = models.ImageField(upload_to='gallery_pics',
verbose_name='Image')
def __str__(self):
return self.gala_obj.title
and below is my views.py file
`def detailViewPage(request,slug):
#here i wanted to get one image with the given slug
from `ImagesModel`
a = get_object_or_404(PhotoGallery, slug=slug)
selected_pic = a.picture_gallery.all()
#here i wanted to get all images excluding one
with the given slug
object_2 = ImagesModel.objects.exclude(id=selected_pic.id)
.order_by('-id')[:15]
return render(request,'gallery/photogallery_detail.html',{
'selected_pic':selected_pic,
'object_2':object_2,
})`
below is the error i get
The question is not very clear, but I assume you want to get all pictures associated with an object A. In your B model, give your foreignkey a related name:
class B(models.Model):
a = models.ForeignKey(A,related_name='post_title', related_name='pictures')
image = models.ImageField(upload_to='gallery_pics',
verbose_name='Image')
In your views.py:
a = get_object_or_404(A, slug=slug)
b = a.pictures.all()
I don't know why you named your foreignkey 'title', but the above code will get all the pictures associated with the object A.
The following will work also:
a = get_object_or_404(A, slug=slug)
pictures = a.b_set.all()
If you want to get the slug from an object B, then you can do the following:
b = get_object_or_404(B, id=1)
slug = b.a.slug
I'm working on a multi language application in Django with django-hvad.
I've two models, Category and Post for a Blog app:
class Category(TranslatableModel):
translations = TranslatedFields(
name=models.CharField(
max_length=100,
verbose_name=_(u'Nombre')
)
)
slug = AutoSlugField(
populate_from='name'
)
class Meta:
verbose_name = _(u'Categoría')
verbose_name_plural = _(u'Categorías')
def __unicode__(self):
return self.safe_translation_getter('name', str(self.pk))
class Post(TranslatableModel):
category = models.ForeignKey(
Category,
related_name='posts',
verbose_name=_(u'Categoría')
)
slug = AutoSlugField(
populate_from='title'
)
translations = TranslatedFields(
title=models.CharField(
max_length=100,
verbose_name=_(u'Título')
),
content=RichTextField(
verbose_name=_(u'Contenido')
)
)
class Meta:
verbose_name = _(u'Publicación')
verbose_name_plural = _(u'Publicaciones')
ordering = ['-created']
def __unicode__(self):
return self.safe_translation_getter('title', str(self.pk))
In my admin.py I'm registering my models this way:
from django.contrib import admin
from hvad.admin import TranslatableAdmin
from blog.models import Category, Post
class CategoryAdmin(TranslatableAdmin):
pass
admin.site.register(Category, CategoryAdmin)
class PostAdmin(TranslatableAdmin):
pass
admin.site.register(Post, PostAdmin)
When I'm creating a new Post in the admin interface I'm having Category IDs instead of their names in the category dropdown:
What should I do to have the translated name instead of the ID?