-
Notifications
You must be signed in to change notification settings - Fork 83
Django: Create, Update, Delete rodinių klasės
Iš pradžių sukuriame (patobuliname jau įprastą ListView). Tam, kad šį puslapį galėtų peržiūrėti tik prisijungę vartotojai, paveldime LoginRequiredMixin. Faile library/views:
from django.views import generic
from django.contrib.auth.mixins import LoginRequiredMixin
class BookInstanceListView(LoginRequiredMixin, generic.ListView):
model = BookInstance
context_object_name = "instances"
template_name = 'instances.html'
Sukuriame path, faile library/urls:
path('instances/', views.BookInstanceListView.as_view(), name='instances'),
Sukuriame html, faile instances.html:
{% extends "base.html" %}
{% block "title" %}Knygų egzemplioriai{% endblock%}
{% block "content" %}
<h1>Egzemplioriai:</h1>
{% for instance in instances %}
<p><a href="{% url 'instance' instance.pk %}">{{ instance.book }}</a> - {{ instance.uuid }}<span class="{% if instance.is_overdue %}text-danger{% endif %}"> ({{ instance.due_back }},
{{ instance.get_status_display }})</span></p>
<hr>
{% endfor %}
{% endblock %}
from django.views import generic
from django.contrib.auth.mixins import LoginRequiredMixin
class BookInstanceDetailView(LoginRequiredMixin, generic.DetailView):
model = BookInstance
context_object_name = "instance"
template_name = "instance.html"
Sukuriame path, faile library/urls:
path('instances/<int:pk>', views.BookInstanceDetailView.as_view(), name="instance"),
Sukuriame html. Jei objekto pavadinimas nenurodytas, jo laukus pasiekiame per object.. Faile instance.html.html:
{% extends "base.html" %}
{% block "title" %}Egzempliorius{% endblock%}
{% block "content" %}
<h1>Knygos egzempliorius {{ instance.uuid }}</h1>
<p><strong>Knyga: </strong>{{ instance.book }}</p>
<p><strong>Būsena: </strong>{{ instance.get_status_display }}</p>
<p><strong>Paimta iki: </strong>{{ instance.due_back }}</p>
<p><strong>Paėmė: </strong><img class="rounded-circle" style="width: 30px" src="{{ instance.reader.profile.photo.url }}"> {{ instance.reader }}</p>
{% endblock %}
from django.views import generic
from django.contrib.auth.mixins import LoginRequiredMixin
class BookByUserCreateView(LoginRequiredMixin, generic.CreateView):
model = BookInstance
fields = ['book', 'due_back']
success_url = "/library/instances/"
template_name = 'instance_form.html'
def form_valid(self, form):
form.instance.reader = self.request.user
return super().form_valid(form)
Sukuriame path, faile library/urls:
path('instances/new', views.BookInstanceCreateView.as_view(), name='instance_new'),
Prie knygos egzemplioriaus pridedame metodą:
def get_absolute_url(self):
"""Nurodo konkretaus aprašymo galinį adresą"""
return reverse('book-detail', args=[str(self.id)])
Sukuriame html, faile instance_form.html:
{% extends "base.html" %}
{% block "title" %}Egzemplioriaus kūrimas/redagavimas{% endblock%}
{% block "content" %}
<div class="content-section">
<form method="POST">
{% csrf_token %}
{% load crispy_forms_tags %}
<legend class="border-bottom mb-4">Knygos Egzemplioriaus kūrimas/redagavimas</legend>
{{ form|crispy }}
<div class="form-group">
<button class="btn btn-outline-info" type="submit">Išsaugoti</button>
</div>
</form>
</div>
{% endblock %}
Įdedame į instances.html įdedame mygtuką:
<a class="btn btn-secondary btn-sm mt-1 mb-1" href="{% url 'instance_new' %}">Naujas egzempliorius</a>
PAPILDOMAI:
Jei CreateView view'e prireiktų į formą įdėti kintamąjį (id lauką) iš URL adreso, galime padaryti pavyzdžiui taip:
def form_valid(self, form):
form.instance.reader = User.objects.get(pk=self.kwargs['pk'])
return super().form_valid(form)
Kad knygos įrašą leistų atnaujinti tik tam vartotojui, kuris yra nurodytas jos reader lauke, paveldime UserPassesTestMixin ir perrašome metodą test_func, kuris gražina True tik tuomet, kai reader laukas sutampa su prisijungusiu vartotoju.
from django.views import generic
from django.contrib.auth.mixins import LoginRequiredMixin
from django.contrib.auth.mixins import UserPassesTestMixin
class BookByUserUpdateView(LoginRequiredMixin, UserPassesTestMixin, UpdateView):
model = BookInstance
fields = ['book', 'due_back']
success_url = "/library/instances/"
template_name = 'instance_form.html'
def form_valid(self, form):
form.instance.reader = self.request.user
return super().form_valid(form)
def test_func(self):
instance = self.get_object()
return instance.reader == self.request.user
Sukuriame path, faile library/urls:
path('instances/<int:pk>/update', views.BookInstanceUpdateView.as_view(), name='instance_update'),
Įdedame atnaujinimo nuorodą į failą user_book.html:
{% extends "base.html" %}
{% block "title" %}Knygų egzemplioriai{% endblock%}
{% block "content" %}
<a class="btn btn-secondary btn-sm mt-1 mb-1" href="{% url 'instance_new' %}">Naujas egzempliorius</a>
<br>
<br>
<h1>Egzemplioriai:</h1>
{% for instance in instances %}
<p><a href="{% url 'instance' instance.pk %}">{{ instance.book }}</a> - {{ instance.uuid }}<span class="{% if instance.is_overdue %}text-danger{% endif %}"> ({{ instance.due_back }},
{{ instance.get_status_display }})</span></p>
{% if instance.reader == user %}
<div>
<a class="btn btn-secondary btn-sm mt-1 mb-1" href="{% url 'instance_update' instance.id %}">Redaguoti</a>
</div>
{% endif %}
<hr>
{% endfor %}
{% endblock %}
from django.views import generic
from django.contrib.auth.mixins import LoginRequiredMixin
from django.contrib.auth.mixins import UserPassesTestMixin
class BookInstanceDeleteView(LoginRequiredMixin, UserPassesTestMixin, generic.DeleteView):
model = BookInstance
success_url = "/library/instances/"
context_object_name = "instance"
template_name = 'instance_delete.html'
def test_func(self):
instance = self.get_object()
return instance.reader == self.request.user
Sukuriame path, faile library/urls:
path('instances/<int:pk>/delete', views.BookInstanceDeleteView.as_view(), name='instance_delete'),
Sukuriame html, faile user_book_delete.html:
{% extends "base.html" %}
{% block "title" %}Egzemplioriaus trynimas{% endblock%}
{% block "content" %}
<div class="content-section">
<form method="POST">
{% load crispy_forms_tags %}
{% csrf_token %}
<fieldset class="form-group">
<legend class="border-bottom mb-4">Ištrinti egzempliorių</legend>
<h2>Ar tikrai norite ištrinti knygos egzempliorių {{ instance.uuid }}?</h2>
</fieldset>
<div class="form-group">
<button class="btn btn-outline-danger" type="submit">Taip, ištrinti</button>
<a class="btn btn-outline-secondary" href="{% url 'instances' %}">Atšaukti</a>
</div>
</form>
</div>
{% endblock %}
Įdedame trynimo nuorodą į failą instances.html:
{% extends "base.html" %}
{% block "title" %}Mano Knygos{% endblock%}
{% block "content" %}
<a class="btn btn-secondary btn-sm mt-1 mb-1" href="{% url 'instance_new' %}">Naujas egzempliorius</a>
<br>
<br>
<h1>Egzemplioriai:</h1>
{% for instance in instances %}
<p><a href="{% url 'instance' instance.pk %}">{{ instance.book }}</a> - {{ instance.uuid }}<span class="{% if instance.is_overdue %}text-danger{% endif %}"> ({{ instance.due_back }},
{{ instance.get_status_display }})</span></p>
{% if instance.reader == user %}
<div>
<a class="btn btn-secondary btn-sm mt-1 mb-1" href="{% url 'instance_update' instance.id %}">Redaguoti</a>
<a class="btn btn-danger btn-sm mt-1 mb-1" href="{% url 'instance_delete' instance.id %}">Ištrinti</a>
</div>
{% endif %}
<hr>
{% endfor %}
{% endblock %}
models.py faile, modelyje turi būti DateField (arba DateTimeField?):
class BookInstance(models.Model):
uuid = models.UUIDField(default=uuid.uuid4)
book = models.ForeignKey(to="Book", verbose_name="Knyga", on_delete=models.CASCADE, related_name="instances")
due_back = models.DateField(verbose_name="Bus prieinama", null=True, blank=True)
reader = models.ForeignKey(to=User, on_delete=models.SET_NULL, null=True, blank=True)
view.py faile, CreateView klasėje:
class BookInstanceCreateView(LoginRequiredMixin, generic.CreateView):
model = BookInstance
# fields = ['book', 'due_back']
success_url = "/library/instances/"
template_name = 'instance_form.html'
form_class = InstanceForm
def form_valid(self, form):
form.instance.reader = self.request.user
return super().form_valid(form)
forms.py faile, nauja forma ir papildoma klasė:
from .models import BookReview, Profilis, BookInstance
class DateInput(forms.DateInput):
input_type = 'date'
class UserBookCreateForm(forms.ModelForm):
class Meta:
model = BookInstance
fields = ['book', 'reader', 'due_back']
widgets = {'reader': forms.HiddenInput(), 'due_back': DateInput()}
Dėmesio: jei lauke norite nustatyti DateTime lauką, tai yra ir datą ir laiką, DateInput klasėje input_type reikšmę pakeiskite iš 'date' į "datetime-local".
instance_form.html faile:
{% extends "base.html" %}
{% block "title" %}Egzemplioriaus kūrimas/redagavimas{% endblock%}
{% block "content" %}
<div class="content-section">
<form method="POST">
{% csrf_token %}
{% load crispy_forms_tags %}
<legend class="border-bottom mb-4">Knygos Egzemplioriaus kūrimas/redagavimas</legend>
{{ form|crispy }}
<div class="form-group">
<button class="btn btn-outline-info" type="submit">Išsaugoti</button>
</div>
</form>
</div>
{% endblock %}
Tęsti kurti Django užduotį – Autoservisas:
- Jei reikia, perdaryti vartotojo užsakymų puslapius į ListView ir DetailView klases.
- Padaryti, kad prisijungęs vartotojas galėtų kurti naujus užsakymus (be eilučių, tik pasirinkęs automobilį ir terminą). Panaudoti CreateView
- Padaryti, kad prisijungęs vartotojas galėtų redaguoti savo užsakymus. Panaudoti UpdateView
- Padaryti, kad prisijungęs vartotojas galėtų ištrinti savo užsakymus. Panaudoti DeleteView
- Padaryti, kuriant arba redaguojant užsakymą, datą ir laiką leistų pasirinkti kalendoriuje/laikrodyje (datetimepicker)
- Padaryti, kad vartotojas galėtų savo užsakyme įvesti eilutes (pasirinktas paslaugas ir kiekius). Papildomai - padaryti, kad šias eilutes galima būtų redaguoti/ištrinti.
© Donatas Noreika ir Jotautas Treigys
Dekoratoriai
Iteratoriai ir generatoriai
RegEx
Pillow
NumPy
Pandas
- Pandas I
- Užduotys I
- Atsakymai I
- Pandas II
- Užduotys II
- Atsakymai II
- Pandas III
- Užduotys III
- Atsakymai III
Seaborn
Mašininis mokymasis
- 1 Tiesinės regresijos modelis
- 1 Užduotis
- 1 Atsakymas
- 2 Modeliai - klasifikatoriai
- 2 Užduotis
- 2 Atsakymas
- 3 Modeliai praktikoje
- 3 Užduotis (atnaujinta), atsakymas
- 3 Užduotis
- 3 Atsakymas (kodas su komentarais)
Requests, JSON, API
Web Scraping (Beautiful Soup)
Duomenų bazės
- SQL 1
- Užduotys
- Atsakymai
- SQL 2
- Užduotys
- Atsakymai
- SQL 3
- Užduotys
- Atsakymai
- SQL 4
- Užduotis
- SQL per Python
- Užduotis
- ORM 1
- Užduotys
- ORM 2
- Užduotis
- Atsakymas
Flask
- Įžanga
- Užduotys
- I dalis
- Užduotis
- I dalies kodas (atsakymas)
- II dalis
- Užduotis
- Atsakymas (kodas)
- III dalis
- Užduotis
- Atsakymas
- IV dalis
- Užduotis
- Atsakymas
- Flask Many2one, CRUD
- Flask One2many, many2many CRUD
- Flask: REST API kūrimas
- Flask: API su One2many (kodas)
- Flask: vartotojai
- Flask: nuotraukos pridėjimas, admin puslapis, puslapiavimas
- Flask: password reset, error pages
- Flask: projekto sutvarkymas
- Flask diegimas į serverį
Django
- 1. Įžanga, Modeliai
- 2. Administratoriaus svetainė
- 3. Šablonai
- 4. Views
- 5. Puslapiavimas, Paieška, Nuotraukos
- 6. Autorizacija
- 7. Vartotojai II, HTML laukai
- 8. Registracija, Formos
- 9. Vartotojo profilis
- 10. Create, Update, Delete rodinių klasės
- 11. Vertimai
- Užduotis: Autoservisas
- Biblioteka: kodas iki 6-tos dalies
- Biblioteka: kodas nuo 6-tos dalies
- Django diegimas į serverį
- Django diegimas į serverį 2
Django REST
Odoo
- Kurso programa: projektų valdymas
- 1 pamoka
- 2 pamoka
- 3 pamoka
- 4 pamoka
- 5 pamoka
- 6 pamoka
- 7 pamoka
- 8 pamoka
- 9 pamoka
Linux