Muestra las diferencias entre dos versiones de la página.
| Próxima revisión | Revisión previa | ||
|
fw:djangoadv [2014/05/31 08:55] alfred creado |
fw:djangoadv [2020/05/09 09:25] (actual) |
||
|---|---|---|---|
| Línea 2: | Línea 2: | ||
| ===== Authentication ===== | ===== Authentication ===== | ||
| ==== Use of the user model ==== | ==== Use of the user model ==== | ||
| + | There is only one class in Django which is ''User'', different types of users are instances of this class with other special attributes set. \\ | ||
| + | Main attributes are: username, password, email, first_name, and last_name. However, there are [[https://docs.djangoproject.com/en/dev/ref/contrib/auth/#django.contrib.auth.models.User|others]]. \\ | ||
| + | User classes and helper methods reference: ''https://docs.djangoproject.com/en/dev/ref/contrib/auth/'' | ||
| + | === User creation === | ||
| + | Using ''create_user'' function: | ||
| + | <code python> | ||
| + | from django.contrib.auth.models import User | ||
| + | user = User.objects.create_user('john', 'lennon@thebeatles.com', 'johnpassword') | ||
| + | # At this point, user is a User object that has already been saved to the database. | ||
| + | user.last_name = 'Lennon' | ||
| + | user.save() | ||
| + | </code> | ||
| + | |||
| + | === Change user password === | ||
| + | To change user passwords we'll do: | ||
| + | <code python> | ||
| + | from django.contrib.auth.models import User | ||
| + | u = User.objects.get(username='john') | ||
| + | u.set_password('new password') | ||
| + | u.save() | ||
| + | </code> | ||
| + | |||
| + | === User authentication === | ||
| + | User ''authenticate()'', it takes credentials from keyword arguments and returns a ''User'' object if they were valid, if not returns ''None''. | ||
| + | <code python> | ||
| + | from django.contrib.auth import authenticate | ||
| + | user = authenticate(username='john', password='secret') | ||
| + | if user is not None: | ||
| + | if user.is_active: | ||
| + | print("User is valid, active and authenticated") | ||
| + | else: | ||
| + | print("The password is valid, but the account has been disabled!") | ||
| + | else: | ||
| + | print("The username and password were incorrect.") | ||
| + | </code> | ||
| + | When a request is done, it is provided a ''request.user'' attribute. If the current user has not logged in the attribute will be set to an instance of ''AnonymousUser'', otherwise it will be an instance of ''User''. However you can tell it using ''is_authenticated()'' method: | ||
| + | <code python> | ||
| + | if request.user.is_authenticated(): | ||
| + | # Do something for authenticated users. | ||
| + | else: | ||
| + | # Do something for anonymous users. | ||
| + | </code> | ||
| + | === Login and logout === | ||
| + | To login a user: [[https://docs.djangoproject.com/en/dev/topics/auth/default/#django.contrib.auth.login]]. \\ | ||
| + | To logout use the ''logout'' function: | ||
| + | <code python> | ||
| + | from django.contrib.auth import logout | ||
| + | |||
| + | def logout_view(request): | ||
| + | logout(request) | ||
| + | # Redirect to a success page. | ||
| + | </code> | ||
| ==== Authorization ==== | ==== Authorization ==== | ||
| ==== Customizing authorization ==== | ==== Customizing authorization ==== | ||
| + | * [[https://docs.djangoproject.com/en/dev/topics/auth/customizing/]] | ||
| + | |||
| + | ===== Signals ===== | ||
| + | ==== Signals in Django ==== | ||
| + | Django provides a way of intercept special notifications... | ||
| + | * ''django.db.models.signals.pre_save'' & ''django.db.models.signals.post_save'', sent before or after a model’s save() method is called. | ||
| + | * ''django.db.models.signals.pre_delete'' & ''django.db.models.signals.post_delete'', sent before or after a model’s delete() method or queryset’s delete() method is called. | ||
| + | * ''django.db.models.signals.m2m_changed'', sent when a ManyToManyField on a model is changed. | ||
| + | * ''django.core.signals.request_started'' & ''django.core.signals.request_finished'', sent when Django starts or finishes an HTTP request. | ||
| + | |||
| + | There are [[https://docs.djangoproject.com/en/dev/ref/signals/|ohters]] like ''pre_init'', ''class_prepared'', ''pre_migrate'', ''pre_syncdb'', ''got_request_exception'', ''connection_created''... | ||
| + | ==== Connecting signals ==== | ||
| + | |||
| + | The way to intercept a signal is using the ''connect()'' function or the ''receiver()'' decorator: | ||
| + | <code python> | ||
| + | def my_callback(sender, **kwargs): | ||
| + | print("Request finished!") | ||
| + | # ....... | ||
| + | from django.core.signals import request_finished | ||
| + | request_finished.connect(my_callback) | ||
| + | # ....... | ||
| + | from django.core.signals import request_finished | ||
| + | from django.dispatch import receiver | ||
| + | @receiver(request_finished) | ||
| + | def my_callback(sender, **kwargs): | ||
| + | print("Request finished!") | ||
| + | </code> | ||
| + | |||
| + | The function ''Signal.connect'' has the next argument: | ||
| + | <code python> | ||
| + | Signal.connect(receiver[, sender=None, weak=True, dispatch_uid=None]) | ||
| + | </code> | ||
| + | Its arguments mean: | ||
| + | * Receiver argument is a function defined as: ''def my_callback(sender, <nowiki>**kwargs</nowiki>)''. | ||
| + | * Sender argument concretes a sender class. | ||
| + | * Weak argument avoid Django storing signal handlers as weak references, which is done by default. Thus, if your receiver is a local function, it may be garbage collected. To prevent this, pass ''weak=False'' when you call the signal’s connect() method. | ||
| + | * dispatch_uid, its an unique identifier for a signal receiver in cases where duplicate signals may be sent. | ||
| + | |||
| + | <code python> | ||
| + | from myapp.models import MyModel | ||
| + | @receiver(pre_save, sender=MyModel) | ||
| + | def my_handler(sender, **kwargs): | ||
| + | ... | ||
| + | request_finished.connect(my_callback, dispatch_uid="my_unique_identifier") | ||
| + | </code> | ||
| + | |||
| + | ==== Defining and sending signals ==== | ||
| + | Signals are ''django.dispatch.Signal([providing_args=list])'' instances. ''providing_args'' is a list of the names of arguments the signal will provide to listeners. To declare a ''pizza_done'' signal which provides receivers with toppics and size arguments: | ||
| + | <code python> | ||
| + | import django.dispatch | ||
| + | pizza_done = django.dispatch.Signal(providing_args=["toppings", "size"]) | ||
| + | </code> | ||
| + | To send a signal, call either ''Signal.send()'' or ''Signal.send_robust()''. Both return a list of tuple pairs ''[(receiver, response), ... ]''. They differ in how exceptions raised by receiver functions. ''send()'' does not catch any exceptions raised by receivers; it simply allows errors to propagate. Whereas ''send_robust()'' catches all errors derived from Python’s Exception class, and ensures all receivers are notified of the signal. | ||
| + | <code python> | ||
| + | class PizzaStore(object): | ||
| + | ... | ||
| + | def send_pizza(self, toppings, size): | ||
| + | pizza_done.send(sender=self.__class__, toppings=toppings, size=size) | ||
| + | </code> | ||
| + | To disconnect a receiver from a signal, call ''Signal.disconnect()''. | ||