12
votes

Comment prolongez-vous le modèle de site à Django?

Quelle est la meilleure approche pour étendre le modèle de site à Django? Création d'un nouveau modèle et d'un nouveau modèle au site ou une autre approche qui me permet de sous-classer le modèle de site?

Je préfère le sous-classement, car de manière relative, je suis plus à l'aise, mais je suis préoccupé par l'impact qu'il aura avec l'administrateur intégré.


0 commentaires

6 Réponses :


9
votes

Je viens d'utiliser ma propre sous-classe de site et j'ai créé un administrateur personnalisé pour cela.

Fondamentalement, lorsque vous sous-classez un modèle à Django, il crée FK pointant vers le modèle parent et permet d'accéder aux champs de modèle parent de manière transparente - de la même manière que vous accédez aux attributs de classe des parents au Pyhon. L'administrateur construit ne souffrira de quelque manière que ce soit, mais vous devrez enregistrer des sites modeladmin et enregistrer votre propre modeladmin.


1 commentaires

Qu'en est-il de ces choses? Est-ce qu'ils travaillent toujours? docs.djangoproject.com / FR / DEV / REF / REF / SITS / SITES / ...



4
votes

Si vous ne voulez que modifier le comportement de l'objet, mais que vous n'ajoutez aucun nouveau champ, vous devez envisager d'utiliser un «modèle proxy» (Nouveau dans Django 1.1). Vous pouvez ajouter des méthodes de python supplémentaires aux modèles existants, et plus encore:

C'est ce que le modèle de modèle proxy est pour: créer un proxy pour le modèle d'origine. Vous pouvez créer, supprimer et mettre à jour des instances du modèle proxy et toutes les données seront enregistrées comme si vous utilisiez le modèle d'origine (non proxi). La différence est que vous pouvez changer de choses comme la commande de modèle par défaut ou le gestionnaire par défaut dans le proxy, sans avoir à modifier l'original.

En savoir plus dans La documentation .


1 commentaires

Je cherche à ajouter de nouveaux champs; Mais merci pour l'information. Très utile peu importe.



3
votes

Vous pouvez avoir un autre modèle comme SiteProfile qui a une relation oneoone avec site .


0 commentaires

4
votes

AS de Django 2.2 Il n'y a toujours pas de simple façon simple d'étendre le site code> comme cela peut être effectué pour utilisateur code>. La meilleure façon de le faire est de créer une nouvelle entité et de mettre des paramètres là-bas. C'est le seul moyen que vous souhaitiez exploiter Sites existants Support .

class SiteProfile(models.Model):
    title = models.TextField()
    site = models.OneToOneField(Site, on_delete=models.CASCADE)


0 commentaires

0
votes

Cela fait longtemps que la question a été posée, mais je pense qu'il n'y a pas encore (Django 3.1) une solution facile pour cela, comme la création d'un modèle utilisateur personnalisé. Dans ce cas, la création d'un modèle utilisateur personnalisé héritier à partir du modèle django.contrib.auth.models.abstractuser et de modification d'auth_user_model (dans les paramètres) au modèle utilisateur personnalisé nouvellement créé résout le problème.

Cependant, il peut être atteint pour aussi Modèle de site avec une longue solution écrite ci-dessous: p>

solution h1>

Supposons que vous ayez une application avec le nom noyau. Utilisez cette application pour tout le code ci-dessous, à l'exception du fichier de paramètres. P>

  1. Créer un modèle SiteProfile avec un champ de site ayant une relation d'onseoone avec le modèle de site. J'ai aussi changé son app_label Meta afin qu'il soit vu sous l'application Sites dans l'administrateur. Li> ol> xxx pré>
    1. enregistrer le modèle dans l'administrateur. (dans Core.admin) Li> OL>

      Qu'est-ce que nous avons fait jusqu'à présent était suffisant si vous voulez simplement créer un modèle de profil de site. Cependant, vous voudrez que le premier profil soit créé juste après la migration. Parce que le premier site est créé, mais pas le premier profil qui lui est associé. Si vous ne voulez pas le créer à la main, vous avez besoin de la 3ème étape. P>

      1. écrire ci-dessous le code dans core.apps.py: li> OL>
        # e.g.
        {{ site.name }} 
        {{ site.profiles.long_name }} 
        


0 commentaires

0
votes

Apparemment, vous pouvez également créer un fichier modèles.py dans un dossier que vous ajoutez à installé_apps, avec le contenu suivant:

from django.contrib.sites.models import Site as DjangoSite, SiteManager    
from django.core.exceptions import ImproperlyConfigured    
from django.db import models    
from django.http.request import split_domain_port    
    

# our site model
class Site(DjangoSite):    
    settings = models.JSONField(blank=True, default={})    
    port = models.PositiveIntegerField(null=True)    
    protocol = models.CharField(default='http', max_length=5)    
    
    @property    
    def url(self):    
        if self.port:    
            host = f'{self.domain}:{self.port}'    
        else:    
            host = self.domain    
        return f'{self.protocol}://{host}/'    
    

# patch django.contrib.sites.models.Site.objects to use our Site class
DjangoSite.objects.model = Site      
    

# optionnal: override get_current to auto create site instances 
old_get_current = SiteManager.get_current    
def get_current(self, request=None):    
    try:     
        return old_get_current(self, request)    
    except (ImproperlyConfigured, Site.DoesNotExist):    
        if not request:    
            return Site(domain='localhost', name='localhost')    
        host = request.get_host()    
        domain, port = split_domain_port(host)    
        Site.objects.create(    
            name=domain.capitalize(),    
            domain=host,    
            port=port,    
            protocol=request.META['wsgi.url_scheme'],    
        )    
    return old_get_current(self, request)    
SiteManager.get_current = get_current    


0 commentaires