+ {% include 'plants/includes/plant_card.html' with plant=plant %}
+
+ {% endfor %}
+
+
+
+
+
+
+
Botanical Wonders
+
+
+ Dive into a world of curated botanical knowledge. Explore the intricate details,
+ unique characteristics, and the fascinating science behind nature’s most
+ extraordinary plant species.
+
+
+
+
+
+
+{% endblock %}
\ No newline at end of file
diff --git a/Planteer/main/tests.py b/Planteer/main/tests.py
new file mode 100644
index 0000000..7ce503c
--- /dev/null
+++ b/Planteer/main/tests.py
@@ -0,0 +1,3 @@
+from django.test import TestCase
+
+# Create your tests here.
diff --git a/Planteer/main/urls.py b/Planteer/main/urls.py
new file mode 100644
index 0000000..0770718
--- /dev/null
+++ b/Planteer/main/urls.py
@@ -0,0 +1,9 @@
+from django.urls import path
+from . import views
+
+app_name = "main"
+
+urlpatterns= [
+ path('', views.home_view, name="home_view")
+]
+
diff --git a/Planteer/main/views.py b/Planteer/main/views.py
new file mode 100644
index 0000000..c601d6c
--- /dev/null
+++ b/Planteer/main/views.py
@@ -0,0 +1,9 @@
+from django.shortcuts import render
+from django.http import HttpRequest,HttpResponse
+from plants.models import Plant
+
+# Create your views here.
+
+def home_view(request):
+ latest_plants = Plant.objects.all().order_by('-created_at')[:3]
+ return render(request, "main/home.html", {"plants": latest_plants})
\ No newline at end of file
diff --git a/Planteer/manage.py b/Planteer/manage.py
new file mode 100644
index 0000000..bd0a64a
--- /dev/null
+++ b/Planteer/manage.py
@@ -0,0 +1,22 @@
+#!/usr/bin/env python
+"""Django's command-line utility for administrative tasks."""
+import os
+import sys
+
+
+def main():
+ """Run administrative tasks."""
+ os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'Planteer.settings')
+ try:
+ from django.core.management import execute_from_command_line
+ except ImportError as exc:
+ raise ImportError(
+ "Couldn't import Django. Are you sure it's installed and "
+ "available on your PYTHONPATH environment variable? Did you "
+ "forget to activate a virtual environment?"
+ ) from exc
+ execute_from_command_line(sys.argv)
+
+
+if __name__ == '__main__':
+ main()
diff --git a/Planteer/media/flags/Afghanistan_flage.png b/Planteer/media/flags/Afghanistan_flage.png
new file mode 100644
index 0000000..9be8219
Binary files /dev/null and b/Planteer/media/flags/Afghanistan_flage.png differ
diff --git a/Planteer/media/flags/Brazil_flage.png b/Planteer/media/flags/Brazil_flage.png
new file mode 100644
index 0000000..66454db
Binary files /dev/null and b/Planteer/media/flags/Brazil_flage.png differ
diff --git a/Planteer/media/flags/China_flage.png b/Planteer/media/flags/China_flage.png
new file mode 100644
index 0000000..8a7c582
Binary files /dev/null and b/Planteer/media/flags/China_flage.png differ
diff --git a/Planteer/media/flags/Egypt_flag.png b/Planteer/media/flags/Egypt_flag.png
new file mode 100644
index 0000000..1bc3636
Binary files /dev/null and b/Planteer/media/flags/Egypt_flag.png differ
diff --git a/Planteer/media/flags/France_flage.png b/Planteer/media/flags/France_flage.png
new file mode 100644
index 0000000..aa21452
Binary files /dev/null and b/Planteer/media/flags/France_flage.png differ
diff --git a/Planteer/media/flags/India_flage.png b/Planteer/media/flags/India_flage.png
new file mode 100644
index 0000000..0f95152
Binary files /dev/null and b/Planteer/media/flags/India_flage.png differ
diff --git a/Planteer/media/flags/Italy_flage.png b/Planteer/media/flags/Italy_flage.png
new file mode 100644
index 0000000..1bcc3fc
Binary files /dev/null and b/Planteer/media/flags/Italy_flage.png differ
diff --git a/Planteer/media/flags/Jordan.png b/Planteer/media/flags/Jordan.png
new file mode 100644
index 0000000..7fbf571
Binary files /dev/null and b/Planteer/media/flags/Jordan.png differ
diff --git a/Planteer/media/flags/Kazakhstan_flage.png b/Planteer/media/flags/Kazakhstan_flage.png
new file mode 100644
index 0000000..d9a5b19
Binary files /dev/null and b/Planteer/media/flags/Kazakhstan_flage.png differ
diff --git a/Planteer/media/flags/Lebanon_flag.png b/Planteer/media/flags/Lebanon_flag.png
new file mode 100644
index 0000000..38583f9
Binary files /dev/null and b/Planteer/media/flags/Lebanon_flag.png differ
diff --git a/Planteer/media/flags/Peru_flage.png b/Planteer/media/flags/Peru_flage.png
new file mode 100644
index 0000000..3b1c761
Binary files /dev/null and b/Planteer/media/flags/Peru_flage.png differ
diff --git a/Planteer/media/flags/Philippines_flage.png b/Planteer/media/flags/Philippines_flage.png
new file mode 100644
index 0000000..e9ee447
Binary files /dev/null and b/Planteer/media/flags/Philippines_flage.png differ
diff --git a/Planteer/media/flags/Saudi_Arabia_flag.png b/Planteer/media/flags/Saudi_Arabia_flag.png
new file mode 100644
index 0000000..f694798
Binary files /dev/null and b/Planteer/media/flags/Saudi_Arabia_flag.png differ
diff --git a/Planteer/media/flags/Syria_flag.png b/Planteer/media/flags/Syria_flag.png
new file mode 100644
index 0000000..76f558a
Binary files /dev/null and b/Planteer/media/flags/Syria_flag.png differ
diff --git a/Planteer/media/flags/USA_flage.png b/Planteer/media/flags/USA_flage.png
new file mode 100644
index 0000000..5190360
Binary files /dev/null and b/Planteer/media/flags/USA_flage.png differ
diff --git a/Planteer/media/images/Arabian_Jasmine.jpg b/Planteer/media/images/Arabian_Jasmine.jpg
new file mode 100644
index 0000000..01eb45f
Binary files /dev/null and b/Planteer/media/images/Arabian_Jasmine.jpg differ
diff --git a/Planteer/media/images/Bougainvillea.jpg b/Planteer/media/images/Bougainvillea.jpg
new file mode 100644
index 0000000..2e42c9f
Binary files /dev/null and b/Planteer/media/images/Bougainvillea.jpg differ
diff --git a/Planteer/media/images/Cucumber.jpg b/Planteer/media/images/Cucumber.jpg
new file mode 100644
index 0000000..9479eb4
Binary files /dev/null and b/Planteer/media/images/Cucumber.jpg differ
diff --git a/Planteer/media/images/Eggplant.jpg b/Planteer/media/images/Eggplant.jpg
new file mode 100644
index 0000000..dbfce39
Binary files /dev/null and b/Planteer/media/images/Eggplant.jpg differ
diff --git a/Planteer/media/images/Garlic.jpg b/Planteer/media/images/Garlic.jpg
new file mode 100644
index 0000000..bd273e9
Binary files /dev/null and b/Planteer/media/images/Garlic.jpg differ
diff --git a/Planteer/media/images/Ghaf.jpeg b/Planteer/media/images/Ghaf.jpeg
new file mode 100644
index 0000000..4f31a5e
Binary files /dev/null and b/Planteer/media/images/Ghaf.jpeg differ
diff --git a/Planteer/media/images/Grapes.jpg b/Planteer/media/images/Grapes.jpg
new file mode 100644
index 0000000..0791947
Binary files /dev/null and b/Planteer/media/images/Grapes.jpg differ
diff --git a/Planteer/media/images/Lavender.jpg b/Planteer/media/images/Lavender.jpg
new file mode 100644
index 0000000..f35f31f
Binary files /dev/null and b/Planteer/media/images/Lavender.jpg differ
diff --git a/Planteer/media/images/Peach.jpg b/Planteer/media/images/Peach.jpg
new file mode 100644
index 0000000..4bbb8f0
Binary files /dev/null and b/Planteer/media/images/Peach.jpg differ
diff --git a/Planteer/media/images/Sunflower.jpg b/Planteer/media/images/Sunflower.jpg
new file mode 100644
index 0000000..254000c
Binary files /dev/null and b/Planteer/media/images/Sunflower.jpg differ
diff --git a/Planteer/media/images/Taif_Rose.jpeg b/Planteer/media/images/Taif_Rose.jpeg
new file mode 100644
index 0000000..81828f8
Binary files /dev/null and b/Planteer/media/images/Taif_Rose.jpeg differ
diff --git a/Planteer/media/images/Talh.jpeg b/Planteer/media/images/Talh.jpeg
new file mode 100644
index 0000000..2948dc1
Binary files /dev/null and b/Planteer/media/images/Talh.jpeg differ
diff --git a/Planteer/media/images/Talh_qQ2odeb.jpeg b/Planteer/media/images/Talh_qQ2odeb.jpeg
new file mode 100644
index 0000000..1c2cf2e
Binary files /dev/null and b/Planteer/media/images/Talh_qQ2odeb.jpeg differ
diff --git a/Planteer/media/images/aluli.jpeg b/Planteer/media/images/aluli.jpeg
new file mode 100644
index 0000000..4f5a980
Binary files /dev/null and b/Planteer/media/images/aluli.jpeg differ
diff --git a/Planteer/media/images/apple_1.jpg b/Planteer/media/images/apple_1.jpg
new file mode 100644
index 0000000..6d0877c
Binary files /dev/null and b/Planteer/media/images/apple_1.jpg differ
diff --git a/Planteer/media/images/broccole.jpg b/Planteer/media/images/broccole.jpg
new file mode 100644
index 0000000..6b7543f
Binary files /dev/null and b/Planteer/media/images/broccole.jpg differ
diff --git a/Planteer/media/images/bunana.jpg b/Planteer/media/images/bunana.jpg
new file mode 100644
index 0000000..24e5dc1
Binary files /dev/null and b/Planteer/media/images/bunana.jpg differ
diff --git a/Planteer/media/images/carrot.jpg b/Planteer/media/images/carrot.jpg
new file mode 100644
index 0000000..558c9e8
Binary files /dev/null and b/Planteer/media/images/carrot.jpg differ
diff --git a/Planteer/media/images/mango.jpg b/Planteer/media/images/mango.jpg
new file mode 100644
index 0000000..bb43a83
Binary files /dev/null and b/Planteer/media/images/mango.jpg differ
diff --git a/Planteer/media/images/neem.jpeg b/Planteer/media/images/neem.jpeg
new file mode 100644
index 0000000..acf0a9f
Binary files /dev/null and b/Planteer/media/images/neem.jpeg differ
diff --git a/Planteer/media/images/pineapple.jpg b/Planteer/media/images/pineapple.jpg
new file mode 100644
index 0000000..f938f7d
Binary files /dev/null and b/Planteer/media/images/pineapple.jpg differ
diff --git a/Planteer/media/images/potato.jpg b/Planteer/media/images/potato.jpg
new file mode 100644
index 0000000..9f09fdb
Binary files /dev/null and b/Planteer/media/images/potato.jpg differ
diff --git a/Planteer/media/images/strawberry.jpg b/Planteer/media/images/strawberry.jpg
new file mode 100644
index 0000000..fe7d79b
Binary files /dev/null and b/Planteer/media/images/strawberry.jpg differ
diff --git a/Planteer/media/images/tomato.jpg b/Planteer/media/images/tomato.jpg
new file mode 100644
index 0000000..f101bba
Binary files /dev/null and b/Planteer/media/images/tomato.jpg differ
diff --git a/Planteer/media/images/watermelon.jpg b/Planteer/media/images/watermelon.jpg
new file mode 100644
index 0000000..b104443
Binary files /dev/null and b/Planteer/media/images/watermelon.jpg differ
diff --git a/Planteer/plants/__init__.py b/Planteer/plants/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/Planteer/plants/admin.py b/Planteer/plants/admin.py
new file mode 100644
index 0000000..52fafbd
--- /dev/null
+++ b/Planteer/plants/admin.py
@@ -0,0 +1,22 @@
+from django.contrib import admin
+from .models import Plant, Review, Country
+
+class PlantAdmin(admin.ModelAdmin):
+ list_display = ('name', 'category', 'is_edible', 'created_at')
+
+ search_fields = ('name', 'about', 'used_for')
+
+ list_filter = ('category', 'is_edible', 'created_at')
+
+ ordering = ('-created_at',)
+
+class ReviewAdmin(admin.ModelAdmin):
+ list_display = ('user', 'plant', 'created_at')
+
+ search_fields = ('name', 'comment')
+
+ list_filter = ('plant', 'created_at')
+
+admin.site.register(Plant, PlantAdmin)
+admin.site.register(Review, ReviewAdmin)
+admin.site.register(Country)
\ No newline at end of file
diff --git a/Planteer/plants/apps.py b/Planteer/plants/apps.py
new file mode 100644
index 0000000..478c3ce
--- /dev/null
+++ b/Planteer/plants/apps.py
@@ -0,0 +1,5 @@
+from django.apps import AppConfig
+
+
+class PlantsConfig(AppConfig):
+ name = 'plants'
diff --git a/Planteer/plants/forms.py b/Planteer/plants/forms.py
new file mode 100644
index 0000000..12c4a2a
--- /dev/null
+++ b/Planteer/plants/forms.py
@@ -0,0 +1,25 @@
+from django import forms
+from .models import Plant
+
+class PlantForm(forms.ModelForm):
+ name = forms.CharField(
+ min_length=3,
+ widget=forms.TextInput(attrs={'class': 'form-control', 'placeholder': 'Plant Name'})
+ )
+ about = forms.CharField(
+ min_length=20,
+ widget=forms.Textarea(attrs={'class': 'form-control', 'rows': 4, 'placeholder': 'Write at least 20 characters...'})
+ )
+
+ class Meta:
+ model = Plant
+ fields = "__all__"
+
+ widgets = {
+ 'used_for': forms.Textarea(attrs={'class': 'form-control', 'rows': 2, 'placeholder': 'Usage details...'}),
+ 'category': forms.Select(attrs={'class': 'form-select'}),
+ 'is_edible': forms.CheckboxInput(attrs={'class': 'form-check-input'}),
+ 'image': forms.FileInput(attrs={'class': 'form-control'}),
+ 'countries': forms.MultipleHiddenInput(),
+
+ }
\ No newline at end of file
diff --git a/Planteer/plants/migrations/0001_initial.py b/Planteer/plants/migrations/0001_initial.py
new file mode 100644
index 0000000..e4073b2
--- /dev/null
+++ b/Planteer/plants/migrations/0001_initial.py
@@ -0,0 +1,27 @@
+# Generated by Django 6.0.4 on 2026-04-17 13:39
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ initial = True
+
+ dependencies = [
+ ]
+
+ operations = [
+ migrations.CreateModel(
+ name='Plant',
+ fields=[
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('name', models.CharField(max_length=255)),
+ ('about', models.TextField()),
+ ('used_for', models.TextField()),
+ ('image', models.ImageField(default='images/default.jpg', upload_to='images/')),
+ ('category', models.CharField(choices=[('Tree', 'Tree'), ('Fruit', 'Fruit'), ('Vegetable', 'Vegetable'), ('Flower', 'Flower')], default='Tree', max_length=50)),
+ ('is_edible', models.BooleanField(default=False)),
+ ('created_at', models.DateTimeField(auto_now_add=True)),
+ ],
+ ),
+ ]
diff --git a/Planteer/plants/migrations/0002_review.py b/Planteer/plants/migrations/0002_review.py
new file mode 100644
index 0000000..7a41272
--- /dev/null
+++ b/Planteer/plants/migrations/0002_review.py
@@ -0,0 +1,24 @@
+# Generated by Django 6.0.4 on 2026-04-20 08:27
+
+import django.db.models.deletion
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('plants', '0001_initial'),
+ ]
+
+ operations = [
+ migrations.CreateModel(
+ name='Review',
+ fields=[
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('name', models.CharField(max_length=255)),
+ ('comment', models.TextField()),
+ ('created_at', models.DateTimeField(auto_now_add=True)),
+ ('plant', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='reviews', to='plants.plant')),
+ ],
+ ),
+ ]
diff --git a/Planteer/plants/migrations/0003_country_plant_countries.py b/Planteer/plants/migrations/0003_country_plant_countries.py
new file mode 100644
index 0000000..b835f4a
--- /dev/null
+++ b/Planteer/plants/migrations/0003_country_plant_countries.py
@@ -0,0 +1,29 @@
+# Generated by Django 6.0.4 on 2026-04-21 13:42
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('plants', '0002_review'),
+ ]
+
+ operations = [
+ migrations.CreateModel(
+ name='Country',
+ fields=[
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('name', models.CharField(max_length=100)),
+ ('flag', models.ImageField(upload_to='flags/')),
+ ],
+ options={
+ 'verbose_name_plural': 'Countries',
+ },
+ ),
+ migrations.AddField(
+ model_name='plant',
+ name='countries',
+ field=models.ManyToManyField(related_name='plants', to='plants.country'),
+ ),
+ ]
diff --git a/Planteer/plants/migrations/0004_remove_review_name_review_user.py b/Planteer/plants/migrations/0004_remove_review_name_review_user.py
new file mode 100644
index 0000000..f6c6106
--- /dev/null
+++ b/Planteer/plants/migrations/0004_remove_review_name_review_user.py
@@ -0,0 +1,26 @@
+# Generated by Django 6.0.4 on 2026-04-26 16:12
+
+import django.db.models.deletion
+from django.conf import settings
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('plants', '0003_country_plant_countries'),
+ migrations.swappable_dependency(settings.AUTH_USER_MODEL),
+ ]
+
+ operations = [
+ migrations.RemoveField(
+ model_name='review',
+ name='name',
+ ),
+ migrations.AddField(
+ model_name='review',
+ name='user',
+ field=models.ForeignKey(default=1, on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL),
+ preserve_default=False,
+ ),
+ ]
diff --git a/Planteer/plants/migrations/__init__.py b/Planteer/plants/migrations/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/Planteer/plants/models.py b/Planteer/plants/models.py
new file mode 100644
index 0000000..46895a3
--- /dev/null
+++ b/Planteer/plants/models.py
@@ -0,0 +1,46 @@
+from django.db import models
+from django.contrib.auth.models import User
+
+# Create your models here.
+
+class Country(models.Model):
+ name = models.CharField(max_length=100)
+ flag = models.ImageField(upload_to='flags/')
+
+ def __str__(self):
+ return self.name
+
+ class Meta:
+ verbose_name_plural = "Countries"
+
+class Plant(models.Model):
+
+ class Category(models.TextChoices):
+ TREE = "Tree", "Tree"
+ FRUIT = "Fruit", "Fruit"
+ VEGETABLE = "Vegetable", "Vegetable"
+ FLOWER = "Flower", "Flower"
+
+ name = models.CharField(max_length=255)
+ about = models.TextField()
+ used_for = models.TextField()
+ image = models.ImageField(upload_to="images/", default="images/default.jpg")
+
+ category = models.CharField(
+ max_length=50,
+ choices=Category.choices,
+ default=Category.TREE
+ )
+
+ is_edible = models.BooleanField(default=False)
+ created_at = models.DateTimeField(auto_now_add=True)
+ countries = models.ManyToManyField(Country, related_name='plants')
+
+ def __str__(self):
+ return self.name
+
+class Review(models.Model):
+ plant = models.ForeignKey(Plant, on_delete=models.CASCADE, related_name="reviews")
+ user = models.ForeignKey(User, on_delete=models.CASCADE)
+ comment = models.TextField()
+ created_at = models.DateTimeField(auto_now_add=True)
\ No newline at end of file
diff --git a/Planteer/plants/templates/plants/add_plant.html b/Planteer/plants/templates/plants/add_plant.html
new file mode 100644
index 0000000..138f057
--- /dev/null
+++ b/Planteer/plants/templates/plants/add_plant.html
@@ -0,0 +1,92 @@
+{% extends "main/base.html" %}
+
+{% block content %}
+
+
+
+
+
+ {% if plant %} Update {{ plant.name }} {% else %} Add New Plant {% endif %}
+
+
+
+
+
+
+
+
+
+
+
+
+{% endblock %}
\ No newline at end of file
diff --git a/Planteer/plants/templates/plants/all_plants.html b/Planteer/plants/templates/plants/all_plants.html
new file mode 100644
index 0000000..3f0f588
--- /dev/null
+++ b/Planteer/plants/templates/plants/all_plants.html
@@ -0,0 +1,41 @@
+{% extends "main/base.html" %}
+{% load static %}
+
+{% block content %}
+
+
+
+
+
+ {% if request.user.is_authenticated and request.user.is_staff %}
+
+ ADD NEW PLANT
+
+ {% endif %}
+
+
+
+
+ {% for plant in plants %}
+
+ {% include 'plants/includes/plant_card.html' with plant=plant %}
+
+ {% empty %}
+
+
NO PLANTS FOUND IN THIS CATEGORY.
+
+ {% endfor %}
+
+
+
+
+{% endblock %}
\ No newline at end of file
diff --git a/Planteer/plants/templates/plants/country_plants.html b/Planteer/plants/templates/plants/country_plants.html
new file mode 100644
index 0000000..c5105f4
--- /dev/null
+++ b/Planteer/plants/templates/plants/country_plants.html
@@ -0,0 +1,34 @@
+{% extends 'main/base.html' %}
+
+{% block content %}
+
+
+
+
+
+
+
+
Native Plants in {{ country.name }}
+
Botanical collection of this region.
+
+
+
+ {% for plant in plants %}
+ {% include 'plants/includes/plant_card.html' with plant=plant %}
+ {% empty %}
+
+
No records found for this country.
+
+ {% endfor %}
+
+
+
+
+{% endblock %}
\ No newline at end of file
diff --git a/Planteer/plants/templates/plants/includes/plant_card.html b/Planteer/plants/templates/plants/includes/plant_card.html
new file mode 100644
index 0000000..fbeafa1
--- /dev/null
+++ b/Planteer/plants/templates/plants/includes/plant_card.html
@@ -0,0 +1,33 @@
+{% load static %}
+