2009-06-16 5 views
2

Ich verwende Django-Voting als Abstimmungsanwendung für zwei meiner Modelle. Diese beiden Modelle haben Felder "Autor".Wie kann ich Benutzer, die auf ihr eigenes Modell abstimmen, einschränken?

Wie kann ich einen Benutzer davon abhalten, an einem Modell teilzunehmen, für das dieser bestimmte Benutzer als Autor festgelegt wurde, ohne die Django-Voting-App zu ändern?

Django Middleware ist das erste, was mir in den Sinn kommt, aber ich verstehe nicht, es ist "proces_view" -Funktion. Wenn Sie Middleware für den richtigen Weg halten, können Sie ein Beispiel dafür geben.

Antwort

4

Fügen Sie diesen Code überall in Ihrem settings.py:

from voting.managers import VoteManager 

def check_user(func): 
    def wrapper(self, obj, user, vote): 
     if obj.user != user: 
      return func(self, obj, user, vote) 
     else: 
      return None 
      # or raise some exception 
    return wrapper 

VoteManager.record_vote = check_user(VoteManager.record_vote) 

ich diesen Code nicht ausgeführt haben, vielleicht ist es falsch, aber ich hoffe Idee klar

+0

Ja, die Idee ist klar. Und es funktioniert. Nur zur späteren Bezugnahme kann dieser Code nicht in settings.py übernommen werden. Lege es in eine Datei, die mit Ausnahme von settings.py ausgeführt wird. Zum Beispiel in models.py in Ihrer Anwendung. – aleksandar

+0

Ich denke, das ist der bessere Weg, es zu tun. Auf diese Weise wird die Logik auch für AJAX-Aufrufe geschrieben und befindet sich an einer Stelle. – aleksandar

+0

Seien Sie vorsichtig mit diesem Code, wenn Objekte in Ihrem Projekt vorhanden sind, über die abgestimmt werden kann und die kein Attribut 'user' haben. In diesem Fall müssen Sie entweder einen hasattr (obj, 'user') hinzufügen oder alles in einen try umwandeln ... außer AttributeError. –

2

Anstatt einen Middleware-Hack, warum Anfragen nicht auf diese bestimmte URI durch eine andere Ansicht umleiten? Dann können Sie die von Ihnen gewünschte Logik ausführen und anschließend gegebenenfalls die ursprüngliche Ansicht aufrufen.

+0

das habe ich gemacht;) – Jiaaro

+0

Das ist so offensichtlich, ich weiß nicht, warum ich es nicht an erster Stelle getan habe. Beide Antworten sind richtig. Was zu akzeptieren :)? – aleksandar

+0

Der Nachteil dieses Ansatzes ist, dass Sie zusätzliche Datenbankabfragen machen müssen, um das Objekt abzurufen, auf dem abgestimmt wird, das dann innerhalb der eigenen Ansicht von django-voting wiederholt wird. Die andere Lösung ist also effizienter und TROCKENER, obwohl diese keine Monkey-Anpassung erfordert. –

0

Eine weitere Idee, die post_save signal zu verwenden ist

wie so:

from django.db.models.signals import post_save 
from voting.models import Vote 

def check_user(sender, instance, **kwargs): 
    if instance.user == instance.object.user: 
     instance.delete() 
     # do some other stuff to tell the user it didn't work 

post_save.connect(check_user, sender=Vote) 

der Vorteil dieser vs overr tun Iding VoteManager.record_vote ist, dass es weniger ist eng an das Abstimmungsmodul gekoppelt ist, und wenn sie Änderungen vornehmen ist es weniger wahrscheinlich, dass der Code

bearbeiten brechen: wie in Glader Antwort, müssen Sie sicherstellen, dass alle Objekte du bist Abstimmungen haben ein "Benutzer" -Attribut.

+0

Ja das ist gutes Beispiel zu. – aleksandar

Verwandte Themen