i developed a blog project by watching many open-source courses and create my own django custom admin dashboard where i want to add a category option to my blog project, i have watched some tutorial on as well but couldn't find them helpful
models.py
from django.db import models
from django.forms import ModelForm
from farmingwave.models import BaseHeader,Submenu
class Category(models.Model):
mainmenu=models.ForeignKey(BaseHeader,null=True,on_delete=models.SET_NULL)
submenu=models.ForeignKey(Submenu,on_delete=models.CASCADE)
class AdSideMenu(models.Model):
title_id = models.AutoField(primary_key=True)
title_name = models.TextField()
url = models.TextField()
priority = models.IntegerField()
submenu_status = models.TextField()
class Meta:
db_table = 'admin_side'
class CreateBlog(models.Model):
id = models.AutoField(primary_key=True)
blog_Title = models.TextField(max_length=100)
content = models.TextField(max_length=5000)
category = models.ForeignKey(Category,null=True,on_delete=models.SET_NULL)
class Meta:
db_table = 'create_blog'
they are inhereting data from another app
models.py
`class BaseHeader(models.Model):
main_id = models.AutoField(primary_key=True)
title_name = models.TextField()
url = models.TextField()
priority = models.IntegerField()
submenu_status = models.TextField("false")
class Meta:
db_table = 'base_header'
class Submenu(models.Model):
sub_id = models.AutoField(primary_key=True)
main_id = models.IntegerField()
sub_name = models.TextField()
url = models.TextField()
priority = models.IntegerField()
mainmenu=models.ForeignKey(BaseHeader,on_delete=models.CASCADE)
class meta:
db_table = 'base_subheader'`
and the view function:
def create_blog(request):
if request.method =='POST':
form = CreateBlogForm(request.POST)
if form.is_valid():
form.save()
form = CreateBlogForm()
else:
form = CreateBlogForm()
base = BaseHeader.objects.all()
sub = Submenu.objects.all()
create = CreateBlog.objects.all()
category = Category.objects.all()
context = {
'form' : form,
'createblog' : create,
'category' : category,
'menu' : base,
'sub_menu' : sub,
Why not make the category a select item?
CATEGORY_CHOICES = (
('sports', 'sports'),
('tech', 'tech'),
('politics', 'politics')
)
category = models.CharField(max_length=100, choices=CATEGORY_CHOICES, blank=False)
You'd be able to access it like any other field now, so let's say the user clicked on "Politics articles" you can add a .filter(category="politics") and access it in the templates through {{ article.category }}
I don't know why there are all of these lines in your code, nor do I know the scale of your project, but that's how I would go about doing it.
Related
I'm creating a dashboard to edit a tour app.
Per tour I have a child record in which I define steps. The 2 models look like this:
models.py
class Tour(models.Model):
tour_id = models.CharField(primary_key=True,unique=True, max_length=10)
country = models.ForeignKey(Countries, models.DO_NOTHING, db_column='country')
language = models.ForeignKey(Language, models.DO_NOTHING, db_column='language')
lastupddtm = models.DateTimeField(default=timezone.now)
productid = models.CharField(max_length=50)
title = models.CharField(max_length=50)
description = models.CharField(max_length=100)
descrlong = models.CharField(max_length=1000)
live = models.CharField(max_length=1)
image = models.ImageField(upload_to=upload_tour_image, storage=OverwriteStorage(), blank=True, null=True)
class Meta:
db_table = 'tour'
verbose_name_plural = "tour"
def get_language_flag(self):
return self.language.flag.url
def __str__(self):
return str(self.tour_id) + ' - ' + str(self.title) + ' - ' + str(self.description)
class Toursteps(models.Model):
# tour_id = models.OneToOneField(Tour, models.DO_NOTHING, db_column='tour_id')
tour = models.ForeignKey(Tour, related_name='toursteps', on_delete=models.CASCADE)
step = models.IntegerField(unique=True)
title = models.CharField(max_length=50)
description = models.CharField(max_length=100)
descrlong = models.CharField(max_length=1000)
audiotext = models.TextField()
latitude = models.FloatField()
longitude = models.FloatField()
radius = models.FloatField()
image = models.ImageField(upload_to=upload_tour_step_image, blank=True, null=True)
class Meta:
db_table = 'tourSteps'
verbose_name_plural = "tourSteps"
def __str__(self):
return str(self.tour) + "|" + str(self.step)
After I created a Tour, I go to a detail page. From there I can click a link to add a step for this tour.
This is where the problem is. I pass the tour_id as a variable into the url, but I can't find a way to pick it up in the CreateView of the step.
urls.py
urlpatterns = [
path('tour/<str:pk>/detail', views.TourDetailView.as_view(), name='tour_detail'),
path('tour/<str:pk>/edit', views.UpdateTourView.as_view(), name='tour_edit'),
path('tour/<str:pk>/remove', views.DeleteTourView.as_view(), name='tour_remove'),
path('tour/<str:tour_id>/step/new', views.CreateTourStepView.as_view(), name='tour_step_new')
]
Tour detail view
<p><span class="glyphicon glyphicon-plus"></span></p>
views.py
class CreateTourStepView(LoginRequiredMixin,CreateView):
login_url = '/login/'
redirect_field_name = 'tour_admin/tour_list.html'
success_url = '/'
form_class = TourStepForm
model = Toursteps
def get_context_data(self, **kwargs):
context = super(CreateTourStepView, self).get_context_data(**kwargs)
print(context['tour_id'])
return context
forms.py
class TourStepForm(forms.ModelForm):
class Meta():
model = Toursteps
#fields = '__all__'
exclude = ('tour',)
def form_valid(self, form):
if form.is_valid():
form.instance.tour_id = self.request.GET("tour_id")
form.instance.save()
return HttpResponseRedirect(self.get_success_url())
def get_success_url(self):
return reverse('tour_detail', kwargs={'pk':form.instance.tour_id})
First, your form_valid() and get_success_url() methods belong in your view, not in your form.
Second, the tour_id is passed to the view's kwargs, it's not a query parameter, hence not in self.request.GET. You can find it in self.kwargs.
Third, you need to actually fetch the Tour from your database, not just assign the tour_id. I could post to any tour_id if I wanted and there's no guarantee the tour_id belongs to an actual Tour object. Return a 404 if the tour doesn't exist. And if it exists, assign it to the tour step.
Finally, you should not assign to and save form.instance. You should get the instance using step = form.save(commit=False), then assign to step and save step.
models.py
class Product(models.Model):
title = models.CharField(max_length=200)
description = models.TextField()
price = models.DecimalField(decimal_places=5,max_digits= 1500)
summary = models.TextField()
featured = models.BooleanField()
def __str__(self):
return self.title
# return f'product title:{self.title}-product price:{self.price}'workok
class Meta:
ordering = ('-price',)
class Opinion(models.Model):
name = models.CharField(max_length=20)
email = models.EmailField(max_length=20)
body = models.TextField()
opinion_date = models.DateTimeField(auto_now_add=True)
active = models.BooleanField(default=False)
product = models.ForeignKey(Product, on_delete=models.CASCADE, related_name='opinion_set')
def __str__(self):
return f'({self.name}) add opinion about ({self.product})'
forms.py:
from django.forms import ModelForm
from .models import Product #space after from keyword
class OpinionModelForm(ModelForm):
class Meta:
model = Product
fields = ['name','email','body','product']
invalid in code line :
fields = ['name','email','body','product'] #---- NOT WORK !!!
, but if i change above code to :
fields = "__all__" # ----it is WORKing ok without any problem !!
question : what is the error? I am not need all the fields in the Product model (like active boolean field), I need only 'name','email','body','product' fields .
According to the error and the code you provided the main problem is that you made a mistake in chosing model in serializer:
class OpinionModelForm(ModelForm):
class Meta:
model = Product
fields = ['name','email','body','product']
Serializer name is OpinionModelForm and listed fields belong to Opinion so I guess you actually wanted to serialize Opinion and no Product as you defined at this line:
model = Product
Simply change it to:
model = Opinion
I have a Task model. I want to assign task to multiple users so i have taken ManytoMany relationship. So Django is creating a ManytoMany table but i want to track that which user has completed task and when. So I took intermediary model by using through='TaskComplete'. Now I can not see task_assign_to feild in form. And even i declare in modelForms and submit it gives below error.
Cannot set values on a `ManyToManyField` which specifies an intermediary model. Use audit.TaskComplete's Manager instead.
Now I want that admin selects the user from main form and into intermediary model.
I tried but can not find any solution for this. below is my code. Please guide me how to do it?
My Model:
class Task(models.Model):
task_audit_title = models.ForeignKey(MainAudit,on_delete= models.CASCADE, related_name='audit_title_for_task',verbose_name= ('Audit Title'))
task_subtask_name = models.ManyToManyField(SubTask, related_name='subtask_for_task',verbose_name= ('Subtask Title'))
task_subject = models.CharField(verbose_name= ('Task Subject'),max_length=100,blank=False)
task_description = models.CharField(verbose_name= ('Task Description'),max_length=1000,blank=True)
task_assign_to = models.ManyToManyField(User, related_name='task_assign_to', through='TaskComplete')
task_assign_by = models.ForeignKey(User,on_delete= models.CASCADE, related_name='task_crt_by')
task_deadline = models.DateTimeField(null=True,blank=True)
task_perticulars = models.ManyToManyField(Perticular, related_name='task_perticular', blank=True)
task_created_time = models.DateTimeField(default=timezone.now)
task_modified_by = models.ForeignKey(User,on_delete= models.CASCADE, related_name='task_mod_by', null=True, blank=True)
task_modified_time = models.DateTimeField(null=True,blank=True)
is_del = models.BooleanField(default=0)
class Meta:
permissions = (
("change_temp_delete_task", "Can delete temporarily"),
)
def __str__(self):
return self.task_subject
def get_absolute_url(self):
return reverse('create-task')
class TaskComplete(models.Model):
task_title = models.ForeignKey(Task,on_delete= models.CASCADE, related_name='assigned_task')
is_completed = models.BooleanField(default=0)
task_cmt_by_doer = models.CharField(verbose_name= ('Submit Comment'),max_length=100,blank=True)
completed_by = models.ForeignKey(User,on_delete= models.CASCADE, related_name = 'task_completed_by')
completed_time = models.DateTimeField(null=True,blank=True)
My View:-
class TaskCraeteView(LoginRequiredMixin,SuccessMessageMixin,CreateView):
# permission_required = 'Company.add_company'
model=Task
success_message = " Task Craeted successfully!"
reverse_lazy('create-task')
login_url = 'login'
template_name = 'create-task'
form_class = TaskCreateForm
# fields =[]
def form_valid(self,form):
form.instance.task_assign_by = self.request.user
My traceback my traceback link
My Form
class TaskCreateForm(forms.ModelForm):
class Meta:
model = Task
fields = ['task_audit_title','task_subtask_name','task_subject','task_description',
'task_assign_to','task_deadline','task_perticulars']
Here is my model:
class Browser(models.Model):
profile_name = models.CharField(max_length=400)
browser_type = (
('fr', 'Firefox'),
('ch', 'Chrome'),
('op', 'Opera'),
('ot', 'Other'),
)
browser_name = models.CharField(choices=browser_type, max_length=2)
device_name = models.CharField(max_length=400)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
class Bookmark(models.Model):
browser = models.ForeignKey(Browser, on_delete=models.CASCADE, null=True, blank=True)
title = models.TextField()
url = models.TextField()
iv = models.TextField()
salt = models.TextField()
iteration = models.IntegerField(default=1500)
tags = TaggableManager()
I only want to update certain fields, so here is the modelform
class BookmarkFormEdit(ModelForm):
class Meta:
model = Browser
exclude = ('tags', 'browser_name', 'device_name', 'profile_name')
but my problem is, values are not updating as expected . Here is the view:
def bookmark_edit(request, pk=None):
if request.method == 'POST':
bookmark = Bookmark.objects.get(pk=pk)
frm = BookmarkFormEdit(request.POST, instance=bookmark)
print(request.POST.get('iteration')) // printing correct value from front-end
if frm.is_valid():
x = frm.save()
print(x.iteration) // not saving the new value !
return JsonResponse({'status': 'created'})
else:
return JsonResponse({'error': frm.errors})
return render(request, 'bookmark_edit.html', {'pk': pk})
You are incorrectly defined model in the form. You should use Bookmark model instead of Browser.
class BookmarkFormEdit(ModelForm):
class Meta:
model = Bookmark
You may need to define fields to include/exclude as you want for this model.
I have following scenario:
There are Containers.
Each Container has Contents.
There are Consumers.
Each Consumer measures temperature of Contents
I have Django admin page that shows:
Consumer
Container Content
Container Content Temperature
Date when Temperature was measured
I need this page to show also name of 'Parent Container' for 'Container Content'
How can I do it?
Here is content of my models.py and admin.py
in models.py:
class Container_Model(models.Model):
container_name = models.CharField(max_length=200)
def __str__(self):
return unicode(self.container_name)
class Container_Content_Model(models.Model):
container_content_name = models.CharField(max_length=200, )
parent_container = models.ForeignKey(Container_Model,
related_name="parent_container", on_delete=models.CASCADE)
container_content_consumers =
models.ManyToManyField(Container_Consumer_Model)
def __str__(self):
return unicode(self.container_content_name,)
class Container_Consumer_Model(models.Model):
container_consumer_name = models.CharField(max_length=200)
def __str__(self):
return unicode(self.container_consumer_name)
class Container_Content_Temperature_Model(models.Model):
container_content = models.ForeignKey(Container_Content_Model)
container_consumer = models.ForeignKey(Container_Consumer_Model)
container_content_temperature = models.CharField(max_length=64,
blank=True, null=True)
container_content_temperature_measured_at = models.DateField()
def __str__(self):
return unicode(self.container_content_temperature)
in admin.py:
#admin.register(models.Container_Content_Temperature_Model)
class container_content_temperature_model_admin(admin.ModelAdmin):
list_display = (
'container_consumer',
'container_content',
'container_content_temperature',
'container_content_temperature_measured_at',
)