to initialise a django app:
django-admin startproject projectname
inside the project directory, run python manage.py runserver
to add another app into the project, run the command python manage.py startapp
foldername
then we need to tell python that we added that folder in the python project, so in
the list of installed apps we add:
base.app.BaseConfig, here base is the folder name, app is the app.py file inside
the base folder and then the class name of the app, BaseConfig, now our app is
connected
python manage.py migrate -->we use this first time to make allthe migrations that
are pending that shows in the terminal.
whenever we create any template, then we go to the settings.py file and in the
templates array we enter BASE_DIR / 'templates' #this means that go to the base
directory and find a folder named templates, this way django knows that we have
templates
template inheritance - a system wherein we can use a same peice of template in
multiple html files so that it can be reused and changes made to one template will
affect all the templates easily.
lets say we need to segregate templates of base so that only base can use them, the
name of the templates that only base can use are room and home. So we create a new
folder templates and inside that a folder with a name of the original parent dir,
which is base, hence base -> templates -> base -> then view file
We give a dynamic value in a route like this :
path('room/<str:pk>', views.room, name="room"),
in angular brackets, str means the value would be string and pk is the value
urlpatterns = [
path('', views.home, name="home"),
path('room/<str:pk>', views.room, name="room"),
the name property that we specify here actually comes very handy, for eg, we
need to change the url here from room/ to room_serice/<str:pk>, now this url needs
to be changed everywhere, manually. But this can be dynamically changed if we pass
the name of the url, in our case room, to the template file rather than the url,
here is how:
<h1>{{i.id}} -- <a href="{% url 'room' i.id %}"> {{i.name}} </a></h1> , here
room is the name of the url and the dynamic value in the url .id will be outside
the quotes
def __str__(self):
In Django, the __str__ method is a special method that you can define in your
model classes. This method is used to return a human-readable representation of an
object. It should return a string that represents the object, and this string will
typically be used in the Django admin interface and other places where the model
instances need to be displayed as text.
python manage.py makemigrations -->this command should be used whenever we
create a model so that python can migrate that
this is kind of staging area before applying the migrations .
now to finally apply the migrations we run the command
python manage.py migrate
now to view the admin panel, we add /admin to the localhost base url.
to create a user(Admin level) , we do it by terminal, here is a command:
username: aryavats
email: aryavats@email.com
pass: gyanwati.balram
to register our model to site panel, basically to view it in site panel, we
go to admin.py in our apppfile
and use code:
from .models import modelname
admin.site.register(modelname)
rooms = Room.objects.all()
we import the rooms and the data that is stored using the models.
Rooms.objects.all retrieves all the data
take notes of the models and the migrations and the data flow
from django.forms import ModelForm
from .models import Room
by default django has easily figured a way to create forms for us, for that
we import the two above and
create a class named modelsandform, then it expects two basic data
we specify under meta class(our class), model name in our case its room
and fields set to all means that it will take all the fields from our model and
create
a form for us with that fields
class RoomForm(ModelForm):
class Meta:
model = Room
fields = "__all__"
form.as_p means each element of a form be inside a paragraph tag
The line form = RoomForm(request.POST) is creating an instance of the RoomForm
class and initializing it with the data from the request.POST object. In Django,
when you create a form class that inherits from ModelForm and you pass request.POST
as a parameter during initialization, it populates the form fields with the data
from the POST request. This allows you to validate and save the data provided in
the POST request.
The RoomForm class you provided does not explicitly accept any parameters in its
constructor because it's designed to work with the data from the POST request. When
you call RoomForm(request.POST), Django's form handling mechanism takes care of
populating the form fields with the data from request.POST.
Here's how it works:
RoomForm is defined as a subclass of ModelForm, which means it's designed to work
with a specific model, in this case, the "Room" model.
When you create an instance of RoomForm and pass request.POST as a parameter,
Django's form handling mechanism automatically maps the form fields to the fields
in the "Room" model based on the RoomForm definition.
The form instance (form) is then used to validate the data from the POST request.
If the data in request.POST doesn't match the expected fields in the form, or if it
doesn't meet the validation rules defined in the form class, the form's is_valid
method will return False.
If the data is valid, you can use the form instance to save the data to the
database, as you're doing with form.save().
In summary, even though the RoomForm class doesn't explicitly accept any parameters
in its constructor, it's designed to work with data from the POST request when you
create an instance of it by passing request.POST. Django takes care of populating
the form's fields and validating the data.
when we display the rooms, we need the newly created rooms to be displayed at the
first pos then second, so we did this:
class Room(models.Model):
host = models.ForeignKey(User, models.SET_NULL, null=True)
topic = models.ForeignKey(Topic, on_delete=models.SET_NULL, null=True) #here
set null means if a topic is deleted dont delete a room, make it null and if it is
null then we should allow null values in our db so the next null
name = models.CharField(max_length=200)
description = models.TextField(null=True, blank=True) #if null is set to false,
then it means that the database wont have any value for this model name, if the
value is null, if null is true, then it will have a value for that Blank true means
this field is not REQUIRED when submitting a form
updated = models.DateTimeField(auto_now=True) #this basically adds a timestamp
whenever we save a form or model is updated
created = models.DateTimeField(auto_now_add=True) #this takes a
snapshot/timestamp whenever the instance is first created or whenever a form is
submitted first time only
class Meta:
ordering = ["-updated", "-created"]
def __str__(self):
"""Will return a string output of the model"""
return self.name
class Message(models.M
In this code:
class Meta is a Python class within your model that is used to configure various
aspects of the model's behavior.
ordering is an attribute within the class Meta that specifies the default ordering
of query results for this model. In this case, it's set to ["-updated", "-
created"].
This means that when you query the Room model, the results will be ordered by the -
updated field in descending order (newest first), and if there are records with the
same updated timestamp, they will be further sorted by the -created field in
descending order (newest first).
if we removed the dashes, then it would sort the rooms by ascending order using
updated and created, but if we add dash this just reverses the logic saying last
one goes on top and so on
The class Meta within a Django model allows you to define various options and
behaviors for that model's metadata. In the code you provided for the Room model,
the class Meta block is used to specify the ordering of results when querying the
database for instances of the Room model. Let's break down what the class Meta is
doing in your code:
In this code:
class Meta is a Python class within your model that is used to configure various
aspects of the model's behavior.
ordering is an attribute within the class Meta that specifies the default ordering
of query results for this model. In this case, it's set to ["-updated", "-
created"].
This means that when you query the Room model, the results will be ordered by the -
updated field in descending order (newest first), and if there are records with the
same updated timestamp, they will be further sorted by the -created field in
descending order (newest first).
if we removed the dashes, then it would sort the rooms by ascending order using
updated and created, but if we add dash this just reverses the logic saying last
one goes on top and so on
by default we can access the request object in every template in django, because
django makes it available to every template by default
decorators in django can be used to restrict access to the views based on the
request method.
They will return django.httpresponsenotallowed if the conditions are not met.
def room(request, pk):
room = Room.objects.get(id=pk)
messages = room.message_set.all() #child model name and after that underscore
set, which means give me set of all messages related to this parent
context = {"room": room}
return render(request, 'base/room.html', context=context)
message_set is not a standard attribute of the Room model or a built-in Python
function. Instead, it is likely that the Room model is defined using Django's
Object-Relational Mapping (ORM), and message_set is a related manager automatically
generated by Django for the model to access related objects of the Message model.
The message_set manager is created when you define a ForeignKey or a OneToOneField
from the Message model to the Room model. It allows you to access all related
Message objects associated with a particular Room object without explicitly
defining a custom manager.
In this case, it seems that you have a Message model related to the Room model, and
you can use room.message_set.all() to retrieve all messages associated with the
Room specified by room. This is a convenient way to access related objects in
Django's ORM.
Basically a way to access child elements, here
<small>@{{message.user}} {{message.created|timesince}}</small>
this timesince is a custom filter from django that filters the date and
shows it in the format, since 2 minutes
.order_by("-created") this essentially means that we want to order messages such
that the latest created message appears on the top
In the second approach using .filter(topic__name__icontains=q), setting q to an
empty string (q="") would indeed fetch all results. This is because the icontains
lookup in Django is designed to perform a case-insensitive search for any
occurrence of the specified text within the field.
When you set q to an empty string and use .filter(topic__name__icontains=q), it
effectively matches all rooms where the topic__name field contains any text
(including empty strings and null values) because an empty string is considered to
be present in any string (including empty strings). This behavior is consistent
with the way the icontains lookup works.
So, if you want to retrieve all rooms, including those where topic__name is empty
or null, using .filter(topic__name__icontains=q) with an empty q value is a
suitable approach. It will include all rooms without any filtering based on the
topic name.
{{message.body}} , will output whole message body
but if we use{{message}}, it will output the first 50 chars only, yes thats what
that method __str__ is for
after adding static files css and other separately in directory we go to
settings.py and add this STATICFILES_DIRS = [
BASE_DIR / 'static'
]
after that:
{% load static %}
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<link rel="stylesheet" type="text/css" media="screen" href="{% static
'styles/main.css' %}">
this is how we add the main.css into our main html file
to let django know we have static files inside of base directory
and this is how we can add images:
<img src="{% static 'images/Study.jpg' %}" />
read up many to many relationship
Update A Particular Record By Query
with app.app_context():
book_to_update = db.session.execute(db.select(Book).where(Book.title == "Harry
Potter")).scalar()
book_to_update.title = "Harry Potter and the Chamber of Secrets"
db.session.commit()
Update A Record By PRIMARY KEY
book_id = 1
with app.app_context():
book_to_update = db.session.execute(db.select(Book).where(Book.id ==
book_id)).scalar()
# or book_to_update = db.get_or_404(Book, book_id)
book_to_update.title = "Harry Potter and the Goblet of Fire"
db.session.commit()
Flask-SQLAlchemy also has some handy extra query methods like get_or_404() that we
can use. Since Flask-SQLAlchemy version 3.0 the previous query methods like
Book.query.get() have been deprecated
Delete A Particular Record By PRIMARY KEY
book_id = 1
with app.app_context():
book_to_delete = db.session.execute(db.select(Book).where(Book.id ==
book_id)).scalar()
# or book_to_delete = db.get_or_404(Book, book_id)
db.session.delete(book_to_delete)
db.session.commit()
Put vs patch
put is like replacing that whole entry with a new one whereas patch is updating
any one part or more inside that entry
To create superuser creds when using docker compose
docker-compose run --rm app sh -c "python manage.py createsuperuser"
Apiview vs viewsets in Django
What is a view:
A view handles a request made to a url
Django uses functions