fix form templates
This commit is contained in:
6 files changed
+269
-310
No files matched your search
+92
-77
@@ -1,11 +1,12 @@
|
||||
from django.contrib import admin
|
||||
from django import forms
|
||||
from django.shortcuts import render, redirect
|
||||
from django.urls import path
|
||||
from django.urls import path, reverse
|
||||
from django.http import JsonResponse
|
||||
from django.contrib.admin import site
|
||||
from .models import News, NewsImage, Category, SubCategory, Advertisement, Organization
|
||||
|
||||
|
||||
@admin.register(Organization)
|
||||
class OrganizationAdmin(admin.ModelAdmin):
|
||||
list_display = ("id", "name", "location", "email", "phone_no", "logo")
|
||||
@@ -30,87 +31,101 @@ class NewsImageInline(admin.TabularInline):
|
||||
extra = 1
|
||||
|
||||
|
||||
# class NewsAdminForm(forms.ModelForm):
|
||||
# class Meta:
|
||||
# model = News
|
||||
# fields = ['title', 'description', 'image', 'category', 'sub_category']
|
||||
|
||||
# def __init__(self, *args, **kwargs):
|
||||
# super().__init__(*args, **kwargs)
|
||||
# self.fields['sub_category'].queryset = SubCategory.objects.none()
|
||||
|
||||
# # If we have an instance and category is set
|
||||
# if self.instance and self.instance.pk and self.instance.category:
|
||||
# self.fields['sub_category'].queryset = SubCategory.objects.filter(
|
||||
# category=self.instance.category
|
||||
# )
|
||||
|
||||
# # If form data is passed and category is selected
|
||||
# if args and args[0] and 'category' in args[0]:
|
||||
# try:
|
||||
# category_id = int(args[0]['category'])
|
||||
# self.fields['sub_category'].queryset = SubCategory.objects.filter(
|
||||
# category_id=category_id
|
||||
# )
|
||||
# except (ValueError, TypeError):
|
||||
# pass
|
||||
class NewsAdminForm(forms.ModelForm):
|
||||
class Meta:
|
||||
model = News
|
||||
fields = ["title", "description", "image", "category", "sub_category"]
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
self.fields["sub_category"].queryset = SubCategory.objects.none()
|
||||
|
||||
# If we have an instance and category is set
|
||||
if self.instance and self.instance.pk and self.instance.category:
|
||||
self.fields["sub_category"].queryset = SubCategory.objects.filter(
|
||||
category=self.instance.category
|
||||
)
|
||||
|
||||
# If form data is passed and category is selected
|
||||
if args and args[0] and "category" in args[0]:
|
||||
try:
|
||||
category_id = int(args[0]["category"])
|
||||
self.fields["sub_category"].queryset = SubCategory.objects.filter(
|
||||
category_id=category_id
|
||||
)
|
||||
except (ValueError, TypeError):
|
||||
pass
|
||||
|
||||
|
||||
@admin.register(News)
|
||||
class NewsAdmin(admin.ModelAdmin):
|
||||
# form = NewsAdminForm
|
||||
form = NewsAdminForm
|
||||
inlines = [NewsImageInline]
|
||||
list_display = ['title', 'category', 'sub_category', 'created_at', 'updated_at']
|
||||
|
||||
# def get_urls(self):
|
||||
# urls = super().get_urls()
|
||||
# custom_urls = [
|
||||
# path('add/', self.admin_site.admin_view(self.add_news_view), name='news_news_add'),
|
||||
# path('get_subcategories/', self.admin_site.admin_view(self.get_subcategories), name='get_subcategories'),
|
||||
# ]
|
||||
# return custom_urls + urls
|
||||
# def get_subcategories(self, request):
|
||||
# category_id = request.GET.get('category_id')
|
||||
# if category_id:
|
||||
# subcategories = SubCategory.objects.filter(category_id=category_id).values('id', 'name')
|
||||
# return JsonResponse(list(subcategories), safe=False)
|
||||
# return JsonResponse([], safe=False)
|
||||
# def add_news_view(self, request):
|
||||
# if request.method == 'POST' and '_select_category' in request.POST:
|
||||
# # Just handling category selection
|
||||
# form = self.form(request.POST)
|
||||
# if 'category' in request.POST and request.POST['category']:
|
||||
# category_id = request.POST['category']
|
||||
# form.fields['sub_category'].queryset = SubCategory.objects.filter(
|
||||
# category_id=category_id
|
||||
# )
|
||||
# elif request.method == 'POST':
|
||||
# # Final form submission
|
||||
# form = self.form(request.POST, request.FILES)
|
||||
# if form.is_valid():
|
||||
# news = form.save()
|
||||
# self.message_user(request, "News created successfully.")
|
||||
# return redirect('admin:news_news_change', object_id=news.pk)
|
||||
# else:
|
||||
# form = self.form()
|
||||
|
||||
# # Get all categories for the dropdown
|
||||
# categories = Category.objects.all()
|
||||
|
||||
# # Prepare context for the template
|
||||
# context = {
|
||||
# 'form': form,
|
||||
# **site.each_context(request),
|
||||
# 'categories': categories,
|
||||
# 'opts': self.model._meta,
|
||||
# 'has_view_permission': self.has_view_permission(request),
|
||||
# 'has_add_permission': self.has_add_permission(request),
|
||||
# 'has_change_permission': self.has_change_permission(request),
|
||||
# 'has_delete_permission': self.has_delete_permission(request),
|
||||
# 'app_label': self.model._meta.app_label,
|
||||
# }
|
||||
|
||||
# return render(request, 'admin/app/news/add_form.html', context)
|
||||
list_display = ["title", "category", "sub_category", "created_at", "updated_at"]
|
||||
|
||||
def get_urls(self):
|
||||
urls = super().get_urls()
|
||||
custom_urls = [
|
||||
path(
|
||||
"add/",
|
||||
self.admin_site.admin_view(self.add_news_view),
|
||||
name="news_news_add",
|
||||
),
|
||||
path(
|
||||
"get_subcategories/",
|
||||
self.admin_site.admin_view(self.get_subcategories),
|
||||
name="get_subcategories",
|
||||
),
|
||||
]
|
||||
return custom_urls + urls
|
||||
|
||||
def get_subcategories(self, request):
|
||||
category_id = request.GET.get("category_id")
|
||||
if category_id:
|
||||
subcategories = SubCategory.objects.filter(category_id=category_id).values(
|
||||
"id", "name"
|
||||
)
|
||||
return JsonResponse(list(subcategories), safe=False)
|
||||
return JsonResponse([], safe=False)
|
||||
|
||||
def add_news_view(self, request):
|
||||
if request.method == "POST" and "_select_category" in request.POST:
|
||||
# Just handling category selection
|
||||
form = self.form(request.POST)
|
||||
if "category" in request.POST and request.POST["category"]:
|
||||
category_id = request.POST["category"]
|
||||
form.fields["sub_category"].queryset = SubCategory.objects.filter(
|
||||
category_id=category_id
|
||||
)
|
||||
elif request.method == "POST":
|
||||
# Final form submission
|
||||
form = self.form(request.POST, request.FILES)
|
||||
if form.is_valid():
|
||||
news = form.save()
|
||||
self.message_user(request, "News created successfully.")
|
||||
return redirect(reverse("admin:app_news_changelist"))
|
||||
|
||||
else:
|
||||
form = self.form()
|
||||
|
||||
# Get all categories for the dropdown
|
||||
categories = Category.objects.all()
|
||||
|
||||
# Prepare context for the template
|
||||
context = {
|
||||
"form": form,
|
||||
**site.each_context(request),
|
||||
"categories": categories,
|
||||
"opts": self.model._meta,
|
||||
"has_view_permission": self.has_view_permission(request),
|
||||
"has_add_permission": self.has_add_permission(request),
|
||||
"has_change_permission": self.has_change_permission(request),
|
||||
"has_delete_permission": self.has_delete_permission(request),
|
||||
"app_label": self.model._meta.app_label,
|
||||
}
|
||||
|
||||
return render(request, "admin/app/news/add_form.html", context)
|
||||
|
||||
|
||||
@admin.register(Advertisement)
|
||||
class AdvertisementAdmin(admin.ModelAdmin):
|
||||
|
||||
+6
-4
@@ -1,6 +1,7 @@
|
||||
from django.db import models
|
||||
from django_ckeditor_5.fields import CKEditor5Field
|
||||
|
||||
|
||||
class Organization(models.Model):
|
||||
name = models.CharField(max_length=255)
|
||||
location = models.CharField(max_length=255)
|
||||
@@ -45,10 +46,12 @@ class SubCategory(models.Model):
|
||||
class News(models.Model):
|
||||
id = models.BigAutoField(primary_key=True)
|
||||
title = models.CharField(max_length=255)
|
||||
description = models.TextField(null=True, blank=True, max_length=30000)
|
||||
description = models.TextField(null=True, blank=True, max_length=30000)
|
||||
image = models.ImageField(upload_to="news")
|
||||
category = models.ForeignKey(Category, on_delete=models.CASCADE)
|
||||
sub_category = models.ForeignKey(SubCategory, on_delete=models.CASCADE, null=True, blank=True)
|
||||
sub_category = models.ForeignKey(
|
||||
SubCategory, on_delete=models.CASCADE, null=True, blank=True
|
||||
)
|
||||
created_at = models.DateTimeField(auto_now_add=True)
|
||||
updated_at = models.DateTimeField(auto_now=True)
|
||||
|
||||
@@ -62,7 +65,7 @@ class News(models.Model):
|
||||
|
||||
class NewsImage(models.Model):
|
||||
news = models.ForeignKey(News, on_delete=models.CASCADE, related_name="images")
|
||||
image = models.ImageField(upload_to="news/images")
|
||||
image = models.ImageField(upload_to="news/images", blank=True)
|
||||
|
||||
def __str__(self):
|
||||
return f"Image for {self.news.title}"
|
||||
@@ -77,7 +80,6 @@ class Advertisement(models.Model):
|
||||
def __str__(self):
|
||||
return str(self.id)
|
||||
|
||||
|
||||
class Meta:
|
||||
ordering = ["id"]
|
||||
verbose_name_plural = "ads"
|
||||
@@ -1,212 +1,137 @@
|
||||
{% extends "admin/change_form.html" %}
|
||||
{% load i18n admin_urls static admin_modify %}
|
||||
|
||||
{% block extrahead %}
|
||||
{{ block.super }}
|
||||
<style>
|
||||
/* Main container styling */
|
||||
.jazzmin-form-wrapper {
|
||||
padding: 20px;
|
||||
width: 100%;
|
||||
background-color: white;
|
||||
border-radius: 4px;
|
||||
box-shadow: 0 1px 3px rgba(0,0,0,0.1);
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
/* Form layout */
|
||||
.form-grid {
|
||||
display: grid;
|
||||
grid-template-columns: 180px 1fr;
|
||||
gap: 15px 20px;
|
||||
align-items: start;
|
||||
}
|
||||
|
||||
/* Field styling */
|
||||
.field-wrapper {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.field-label {
|
||||
font-weight: 600;
|
||||
color: #333;
|
||||
margin-top: 8px;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.field-input {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
/* Input styling */
|
||||
input[type="text"],
|
||||
textarea,
|
||||
select {
|
||||
width: 100%;
|
||||
max-width: 500px;
|
||||
padding: 8px;
|
||||
border: 1px solid #ccc;
|
||||
border-radius: 4px;
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
textarea {
|
||||
min-height: 150px;
|
||||
}
|
||||
|
||||
/* Error styling */
|
||||
.field-error {
|
||||
color: #e74c3c;
|
||||
font-size: 0.9em;
|
||||
margin-top: 4px;
|
||||
}
|
||||
|
||||
/* Button styling */
|
||||
.submit-row {
|
||||
margin-top: 30px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
/* Responsive adjustments */
|
||||
@media (max-width: 768px) {
|
||||
.form-grid {
|
||||
grid-template-columns: 1fr;
|
||||
{% extends 'admin/change_form.html' %}
|
||||
{% load static %}
|
||||
{% load widget_tweaks %}
|
||||
{% block extrastyle %}
|
||||
{{ block.super }}
|
||||
<style>
|
||||
.nav-tabs .nav-link { color: #444; }
|
||||
.nav-tabs .nav-link.active {
|
||||
color: #007bff;
|
||||
border-bottom: 2px solid #007bff;
|
||||
}
|
||||
|
||||
.field-label {
|
||||
text-align: left;
|
||||
margin-bottom: 5px;
|
||||
.card {
|
||||
box-shadow: 0 0 1px rgba(0,0,0,.125), 0 1px 3px rgba(0,0,0,.2);
|
||||
margin-bottom: 1rem;
|
||||
border-radius: .25rem;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
.card-header {
|
||||
background-color: #f8f9fa;
|
||||
border-bottom: 1px solid rgba(0,0,0,.125);
|
||||
padding: .75rem 1.25rem;
|
||||
}
|
||||
.card-body { padding: 1.25rem; }
|
||||
.card-footer {
|
||||
background-color: #f8f9fa;
|
||||
border-top: 1px solid rgba(0,0,0,.125);
|
||||
padding: .75rem 1.25rem;
|
||||
}
|
||||
.form-control:focus {
|
||||
border-color: #80bdff;
|
||||
box-shadow: 0 0 0 0.2rem rgba(0,123,255,.25);
|
||||
}
|
||||
</style>
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="jazzmin-form-wrapper">
|
||||
<form method="post" enctype="multipart/form-data" id="news_form" novalidate>
|
||||
{% csrf_token %}
|
||||
|
||||
{% if errors %}
|
||||
<div class="errornote" style="margin-bottom: 20px; padding: 10px; background-color: #fef2f2; border-left: 4px solid #e74c3c; color: #e74c3c;">
|
||||
{% blocktranslate count counter=errors|length %}Please correct the error below.{% plural %}Please correct the errors below.{% endblocktranslate %}
|
||||
{{ form.non_field_errors }}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<div class="form-grid">
|
||||
<!-- Title Field -->
|
||||
<div class="field-label">{{ form.title.label }}:</div>
|
||||
<div class="field-input">
|
||||
{% if form.title.errors %}
|
||||
<div class="field-error">{{ form.title.errors }}</div>
|
||||
{% endif %}
|
||||
{{ form.title }}
|
||||
</div>
|
||||
|
||||
<!-- Description Field -->
|
||||
<div class="field-label">{{ form.description.label }}:</div>
|
||||
<div class="field-input">
|
||||
{% if form.description.errors %}
|
||||
<div class="field-error">{{ form.description.errors }}</div>
|
||||
{% endif %}
|
||||
{{ form.description }}
|
||||
</div>
|
||||
|
||||
<!-- Image Field -->
|
||||
<div class="field-label">{{ form.image.label }}:</div>
|
||||
<div class="field-input">
|
||||
{% if form.image.errors %}
|
||||
<div class="field-error">{{ form.image.errors }}</div>
|
||||
{% endif %}
|
||||
{{ form.image }}
|
||||
</div>
|
||||
|
||||
<!-- Category Field -->
|
||||
<div class="field-label">{{ form.category.label }}:</div>
|
||||
<div class="field-input">
|
||||
{% if form.category.errors %}
|
||||
<div class="field-error">{{ form.category.errors }}</div>
|
||||
{% endif %}
|
||||
<select name="category" id="{{ form.category.id_for_label }}" onchange="updateSubcategories(this.value)">
|
||||
<option value="">---------</option>
|
||||
{% for category in categories %}
|
||||
<option value="{{ category.id }}" {% if form.category.value|stringformat:"s" == category.id|stringformat:"s" %}selected{% endif %}>
|
||||
{{ category.name }}
|
||||
</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<!-- Subcategory Field -->
|
||||
<div class="field-label" id="subcategory_label" {% if not form.sub_category.queryset.exists %}style="display: none;"{% endif %}>
|
||||
{{ form.sub_category.label }}:
|
||||
</div>
|
||||
<div class="field-input" id="subcategory_row" {% if not form.sub_category.queryset.exists %}style="display: none;"{% endif %}>
|
||||
{% if form.sub_category.errors %}
|
||||
<div class="field-error">{{ form.sub_category.errors }}</div>
|
||||
{% endif %}
|
||||
<div id="subcategory_container">
|
||||
{{ form.sub_category }}
|
||||
<div class="container-fluid">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<ul class="nav nav-tabs card-header-tabs">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link active" data-toggle="tab" href="#general">General</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" data-toggle="tab" href="#news-images">News Images</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<form method="post" enctype="multipart/form-data">
|
||||
{% csrf_token %}
|
||||
<div class="card-body">
|
||||
<div class="tab-content">
|
||||
<div class="tab-pane fade show active" id="general">
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<div class="form-group">
|
||||
<label for="{{ form.title.id_for_label }}">{{ form.title.label }}</label>
|
||||
{{ form.title|add_class:"form-control" }}
|
||||
{% if form.title.errors %}<div class="invalid-feedback d-block">{{ form.title.errors }}</div>{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<div class="form-group">
|
||||
<label for="{{ form.category.id_for_label }}">{{ form.category.label }}</label>
|
||||
<select name="category"
|
||||
id="{{ form.category.id_for_label }}"
|
||||
class="form-control"
|
||||
onchange="updateSubcategories(this.value)">
|
||||
<option value="">---------</option>
|
||||
{% for category in categories %}
|
||||
<option value="{{ category.id }}"
|
||||
{% if form.category.value|stringformat:"s" == category.id|stringformat:"s" %}selected{% endif %}>
|
||||
{{ category.name }}
|
||||
</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
{% if form.category.errors %}<div class="invalid-feedback d-block">{{ form.category.errors }}</div>{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group" id="subcategory_wrapper" style="display: none;">
|
||||
<label for="{{ form.sub_category.id_for_label }}">{{ form.sub_category.label }}</label>
|
||||
<div id="subcategory_container">{{ form.sub_category }}</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="{{ form.description.id_for_label }}">{{ form.description.label }}</label>
|
||||
{{ form.description|add_class:"form-control" }}
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="{{ form.image.id_for_label }}">{{ form.image.label }}</label>
|
||||
{{ form.image|add_class:"form-control-file" }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="tab-pane fade" id="news-images">
|
||||
<div class="form-group">
|
||||
<label>Upload Additional News Images</label>
|
||||
<input type="file" name="news_images" multiple class="form-control">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-footer text-right">
|
||||
<button type="submit" class="btn btn-success">Save</button>
|
||||
<button type="submit" name="_addanother" class="btn btn-info">Save and add another</button>
|
||||
<button type="submit" name="_continue" class="btn btn-primary">Save and continue editing</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% for inline_admin_formset in inline_admin_formsets %}
|
||||
{% include inline_admin_formset.opts.template %}
|
||||
{% endfor %}
|
||||
|
||||
<div class="submit-row">
|
||||
<input type="submit" name="_save" value="{% translate 'Save' %}" class="default" style="padding: 8px 16px; background-color: #2980b9; color: white; border: none; border-radius: 4px; cursor: pointer;" />
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
<script>
|
||||
function updateSubcategories(categoryId) {
|
||||
const labelElement = document.getElementById('subcategory_label');
|
||||
const rowElement = document.getElementById('subcategory_row');
|
||||
|
||||
const wrapper = document.getElementById('subcategory_wrapper');
|
||||
const container = document.getElementById('subcategory_container');
|
||||
|
||||
if (!categoryId) {
|
||||
labelElement.style.display = 'none';
|
||||
rowElement.style.display = 'none';
|
||||
wrapper.style.display = 'none';
|
||||
return;
|
||||
}
|
||||
|
||||
// Show elements
|
||||
labelElement.style.display = 'block';
|
||||
rowElement.style.display = 'block';
|
||||
|
||||
// Show loading indicator
|
||||
const container = document.getElementById('subcategory_container');
|
||||
container.innerHTML = '<div style="color: #2980b9;">Loading subcategories...</div>';
|
||||
|
||||
// Fetch subcategories with AJAX
|
||||
|
||||
wrapper.style.display = 'block';
|
||||
container.innerHTML = '<div class="text-info">Loading subcategories...</div>';
|
||||
|
||||
fetch(`{% url 'admin:get_subcategories' %}?category_id=${categoryId}`)
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
if (data.length === 0) {
|
||||
container.innerHTML = '<select id="{{ form.sub_category.id_for_label }}" name="sub_category"><option value="">No subcategories available</option></select>';
|
||||
} else {
|
||||
let selectHtml = `<select id="{{ form.sub_category.id_for_label }}" name="sub_category">`;
|
||||
data.forEach(item => {
|
||||
selectHtml += `<option value="${item.id}">${item.name}</option>`;
|
||||
});
|
||||
selectHtml += '</select>';
|
||||
container.innerHTML = selectHtml;
|
||||
}
|
||||
let selectHtml = `<select name="sub_category" class="form-control">`;
|
||||
selectHtml += `<option value="">Select Subcategory</option>`;
|
||||
data.forEach(item => {
|
||||
selectHtml += `<option value="${item.id}">${item.name}</option>`;
|
||||
});
|
||||
selectHtml += '</select>';
|
||||
container.innerHTML = selectHtml;
|
||||
})
|
||||
.catch(error => {
|
||||
container.innerHTML = '<div style="color: #e74c3c;">Error loading subcategories</div>';
|
||||
console.error('Error:', error);
|
||||
.catch(() => {
|
||||
container.innerHTML = '<div class="text-danger">Error loading subcategories</div>';
|
||||
});
|
||||
}
|
||||
|
||||
// Initialize subcategories if category is already selected
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
const categorySelect = document.getElementById('{{ form.category.id_for_label }}');
|
||||
if (categorySelect.value) {
|
||||
updateSubcategories(categorySelect.value);
|
||||
}
|
||||
});
|
||||
</script>
|
||||
{% endblock %}
|
||||
</script>
|
||||
{% endblock %}
|
||||
+17
-7
@@ -2,11 +2,21 @@
|
||||
from django.urls import path
|
||||
from . import views
|
||||
|
||||
|
||||
urlpatterns = [
|
||||
path('news/', views.NewsListView.as_view(), name='news-list'),
|
||||
path('news/<int:id>/', views.NewsDetailView.as_view(), name='news-detail'),
|
||||
path('categories/', views.CategoryListView.as_view(), name='category-list'),
|
||||
path('subcategories/', views.SubCategoryListView.as_view(), name='subcategory-list'),
|
||||
path('advertisements/', views.AdvertisementListView.as_view(), name='advertisement-list'),
|
||||
path('organization/', views.OrganizationListView.as_view(), name='organization-list'),
|
||||
]
|
||||
path("news/", views.NewsListView.as_view(), name="news-list"),
|
||||
path("news/<int:id>/", views.NewsDetailView.as_view(), name="news-detail"),
|
||||
path("categories/", views.CategoryListView.as_view(), name="category-list"),
|
||||
path(
|
||||
"subcategories/", views.SubCategoryListView.as_view(), name="subcategory-list"
|
||||
),
|
||||
path(
|
||||
"advertisements/",
|
||||
views.AdvertisementListView.as_view(),
|
||||
name="advertisement-list",
|
||||
),
|
||||
path(
|
||||
"organization/", views.OrganizationListView.as_view(), name="organization-list"
|
||||
),
|
||||
]
|
||||
|
||||
+20
-14
@@ -4,49 +4,55 @@ from django.shortcuts import get_object_or_404
|
||||
from rest_framework.exceptions import ValidationError
|
||||
from django.db.models import Q
|
||||
from .serializers import *
|
||||
from .views import News, Category, SubCategory, Advertisement, Organization
|
||||
from .models import News, Category, SubCategory, Advertisement, Organization
|
||||
|
||||
|
||||
class NewsListView(generics.ListAPIView):
|
||||
serializer_class = NewsSerializer
|
||||
|
||||
|
||||
def get_queryset(self):
|
||||
queryset = News.objects.all().order_by('-created_at')
|
||||
category = self.request.query_params.get('category', None)
|
||||
subcategory = self.request.query_params.get('subcategory', None)
|
||||
|
||||
queryset = News.objects.all().order_by("-created_at")
|
||||
category = self.request.query_params.get("category", None)
|
||||
subcategory = self.request.query_params.get("subcategory", None)
|
||||
|
||||
if category:
|
||||
queryset = queryset.filter(
|
||||
Q(category__name__iexact=category) |
|
||||
Q(category__id=category)
|
||||
Q(category__name__iexact=category) | Q(category__id=category)
|
||||
)
|
||||
|
||||
|
||||
if subcategory:
|
||||
queryset = queryset.filter(sub_category_id=subcategory)
|
||||
|
||||
|
||||
return queryset
|
||||
|
||||
|
||||
class NewsDetailView(generics.RetrieveAPIView):
|
||||
queryset = News.objects.all()
|
||||
serializer_class = NewsSerializer
|
||||
lookup_field = 'id'
|
||||
lookup_field = "id"
|
||||
|
||||
|
||||
class CategoryListView(generics.ListAPIView):
|
||||
queryset = Category.objects.prefetch_related('subcategories')
|
||||
queryset = Category.objects.prefetch_related("subcategories")
|
||||
serializer_class = CategoryListSerializer
|
||||
|
||||
|
||||
class SubCategoryListView(generics.ListAPIView):
|
||||
serializer_class = SubCategorySerializer
|
||||
|
||||
|
||||
def get_queryset(self):
|
||||
queryset = SubCategory.objects.all()
|
||||
category_id = self.request.query_params.get('category', None)
|
||||
category_id = self.request.query_params.get("category", None)
|
||||
if category_id:
|
||||
queryset = queryset.filter(category_id=category_id)
|
||||
return queryset
|
||||
|
||||
|
||||
class AdvertisementListView(generics.ListAPIView):
|
||||
queryset = Advertisement.objects.filter(is_active=True)
|
||||
serializer_class = AdvertisementSerializer
|
||||
|
||||
|
||||
class OrganizationListView(generics.ListAPIView):
|
||||
queryset = Organization.objects.all()
|
||||
serializer_class = OrganizationSerializer
|
||||
+13
-12
@@ -40,6 +40,7 @@ INSTALLED_APPS = [
|
||||
"rest_framework",
|
||||
"corsheaders",
|
||||
"django_ckeditor_5",
|
||||
"widget_tweaks",
|
||||
]
|
||||
|
||||
|
||||
@@ -79,24 +80,24 @@ CORS_ORIGIN_ALLOW_ALL = True
|
||||
CORS_ALLOW_ALL_ORIGINS = True
|
||||
CORS_ALLOW_CREDENTIALS = True
|
||||
# Also ensure you have this setting
|
||||
SESSION_COOKIE_SAMESITE = 'Lax' # or 'None' if needed
|
||||
CSRF_COOKIE_SAMESITE = 'Lax' # or 'None' if needed
|
||||
SESSION_COOKIE_SAMESITE = "Lax" # or 'None' if needed
|
||||
CSRF_COOKIE_SAMESITE = "Lax" # or 'None' if needed
|
||||
CSRF_TRUSTED_ORIGINS = [
|
||||
'http://192.168.1.93:5173',
|
||||
'http://192.168.18.4:5173',
|
||||
'http://192.168.1.68:5173',
|
||||
'http://192.168.1.87:5173',
|
||||
'http://localhost:5173'
|
||||
"http://192.168.1.93:5173",
|
||||
"http://192.168.18.4:5173",
|
||||
"http://192.168.1.68:5173",
|
||||
"http://192.168.1.87:5173",
|
||||
"http://localhost:5173",
|
||||
]
|
||||
if DEBUG:
|
||||
CSRF_COOKIE_SECURE = False
|
||||
SESSION_COOKIE_SECURE = False
|
||||
CORS_ALLOWED_ORIGINS = [
|
||||
'http://192.168.1.93:5173',
|
||||
'http://192.168.18.4:5173',
|
||||
'http://192.168.1.68:5173',
|
||||
'http://192.168.1.87:5173',
|
||||
'http://localhost:5173'
|
||||
"http://192.168.1.93:5173",
|
||||
"http://192.168.18.4:5173",
|
||||
"http://192.168.1.68:5173",
|
||||
"http://192.168.1.87:5173",
|
||||
"http://localhost:5173",
|
||||
]
|
||||
|
||||
WSGI_APPLICATION = "newsportal.wsgi.application"
|
||||
|
||||
Reference in new issue
Block a user