Function-based widoki w Django i `rest_framework`.

Function-based widoki w Django i `rest_framework`.
Riddle
Administrator
  • Rejestracja:prawie 15 lat
  • Ostatnio:około 4 godziny
  • Lokalizacja:Laska, z Polski
  • Postów:10078
0

Przychodzę do Django z języków i frameworków, w którym endpointy są odseparowane od metod HTTP.

W laravelu mamy

Kopiuj
Route::get("/user");
Route::post("user");

w springu mamy

Kopiuj
@GetMapping("/user");
@PostMapping("/user");

Matomiast w Django nie ma takiego rozróżnienia. Mam albo Class-based view, w którym precyzuję

Kopiuj
path('user', UserView.as_view())

# Metody połączone
class UserView:
  def get():  
    pass
  def post():
    pass

Albo decoratora @app_view z rest_framework

Kopiuj
@api_view(['GET', 'POST'])
def user(request):
    pass

Tak czy tak, endpoint w Django to jest "jedna" rzecz, i nie znam sposobu jak zadeklarować osobne metody/widoki dla dwóch metod. Znacie jakiś INNY sposób?

PS: Znam class-based! Znam decorator-based! One obie deklarują endpoint na raz. Ja szukam czegoś co je rejestruje osobno tak jak Laravel albo Spring.
PS2: Jeśli jesteś kolejną osobą która chce polecić class-based widoki albo decoratory z rest_framework, to podziękuję, ja szukam czegoś INNEGO.

edytowany 3x, ostatnio: Riddle
Haskell
  • Rejestracja:prawie 10 lat
  • Ostatnio:12 miesięcy
  • Postów:4700
0

W Django ostatnio programowałem 100 lat temu, ale z tego co pamiętam to przekierowujesz ruch do obiektu klasy albo funkcji i dopiero tam go rozdzielasz. Innymi słowy nie ma gotowego rozwiązania gdzie masz osobne metody. Po co Ci to?


Zaglądali do kufrów, zaglądali do waliz, nie zajrzeli do d**y - tam miałem socjalizm. Czesław Miłosz
Riddle
Administrator
  • Rejestracja:prawie 15 lat
  • Ostatnio:około 4 godziny
  • Lokalizacja:Laska, z Polski
  • Postów:10078
0
Haskell napisał(a):

W Django ostatnio programowałem 100 lat temu, ale z tego co pamiętam to przekierowujesz ruch do obiektu klasy albo funkcji i dopiero tam go rozdzielasz. Innymi słowy nie ma gotowego rozwiązania gdzie masz osobne metody. Po co Ci to?

Nie chcę pisać ifów, chciałbym oddzielić logikę od HTTP jeśli mogę.

Haskell
  • Rejestracja:prawie 10 lat
  • Ostatnio:12 miesięcy
  • Postów:4700
1

Jeżeli nie chcesz używać ifów to zostaje class based view gdzie masz osobne metody dla każdej metody HTTP.


Zaglądali do kufrów, zaglądali do waliz, nie zajrzeli do d**y - tam miałem socjalizm. Czesław Miłosz
Riddle
Napisałem przecież w pytaniu, że znam to rozwiązanie i nie tego szukam.
Riddle
Administrator
  • Rejestracja:prawie 15 lat
  • Ostatnio:około 4 godziny
  • Lokalizacja:Laska, z Polski
  • Postów:10078
0
Haskell napisał(a):

Jeżeli nie chcesz używać ifów to zostaje class based view gdzie masz osobne metody dla każdej metody HTTP.

Dziękuję za podsumowanie, tego co napisałem w pytaniu:

TomRiddle napisał(a):

Matomiast w Django nie ma takiego rozróżnienia. Mam albo Class-based view [...]
Albo decoratora @app_view z `rest_framework
[...] endpoint w Django to jest "jedna" rzecz, i nie znam sposobu jak zadeklarować osobne metody/widoki dla dwóch metod.

Ale skupmy się na moim głównym pytaniu:

TomRiddle napisał(a):

Znacie jakiś sposób?

Bo to że

to przekierowujesz ruch do obiektu klasy albo funkcji i dopiero tam go rozdzielasz.

to już wiedziałem i napisałem w pytaniu. Pytałem o inne rozwiązania.

Haskell
  • Rejestracja:prawie 10 lat
  • Ostatnio:12 miesięcy
  • Postów:4700
0

Dostałeś już odpowiedź.


Zaglądali do kufrów, zaglądali do waliz, nie zajrzeli do d**y - tam miałem socjalizm. Czesław Miłosz
Riddle
Tak, że nie znasz. Dziękuję bardzo. Ja pytałem tych, którzy znają.
Haskell
Ostatni raz odpowiadałem na Twój post.
PerlMonk
:D
grski
  • Rejestracja:ponad 9 lat
  • Ostatnio:9 miesięcy
  • Postów:245
0

Patrząc po postach wyżej to imo nie wiem czy trolling czy nie, ale here we go anyway.
https://www.django-rest-framework.org/tutorial/3-class-based-views/

Kopiuj

class SnippetList(APIView):
    """
    List all snippets, or create a new snippet.
    """
    def get(self, request, format=None):
        snippets = Snippet.objects.all()
        serializer = SnippetSerializer(snippets, many=True)
        return Response(serializer.data)

    def post(self, request, format=None):
        serializer = SnippetSerializer(data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data, status=status.HTTP_201_CREATED)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

idąc dalej masz:

Kopiuj
class SnippetDetail(mixins.RetrieveModelMixin,
                    mixins.UpdateModelMixin,
                    mixins.DestroyModelMixin,
                    generics.GenericAPIView):
    queryset = Snippet.objects.all()
    serializer_class = SnippetSerializer

    def get(self, request, *args, **kwargs):
        return self.retrieve(request, *args, **kwargs)

    def put(self, request, *args, **kwargs):
        return self.update(request, *args, **kwargs)

    def delete(self, request, *args, **kwargs):
        return self.destroy(request, *args, **kwargs)

a jeszcze dalej:

Kopiuj
np.

class SnippetList(generics.ListCreateAPIView):
queryset = Snippet.objects.all()
serializer_class = SnippetSerializer

class SnippetDetail(generics.RetrieveUpdateDestroyAPIView):
queryset = Snippet.objects.all()
serializer_class = SnippetSerializer

Kopiuj

Nie ma tu żadnych ifów. Normalnie definiujemy metody, tworzymy klasy które potem rejestrujemy w Routerze

Napisałem książkę - Programowanie z Górskim: Junior Python Developer
Pora na następny krok na drodze po pierwszą pracę w it i WCALE-NIE-MITYCZNE #programista40k? Zapraszam.
Tasmanian Devil
Hej! Twój post prawdopodobnie zawiera niesformatowany kod. Użyj znaczników ``` aby oznaczyć, co jest kodem, będzie łatwiej czytać. (jestem botem, ta akcja została wykonana automatycznie, prawdopodobieństwo 0.99837416)
Riddle
Administrator
  • Rejestracja:prawie 15 lat
  • Ostatnio:około 4 godziny
  • Lokalizacja:Laska, z Polski
  • Postów:10078
0
grski napisał(a):

Patrząc po postach wyżej to imo nie wiem czy trolling czy nie, ale here we go anyway.

Nie ma tu żadnych ifów. Normalnie definiujemy metody, tworzymy klasy które potem rejestrujemy w Routerze

No własnie, klasy.

Ja w pytaniu wyraźnie napisałem że chce różne metody z jednego endpointa rejestrować osobno, żeby oddzielić bardziej logikę controllera od HTTP. Tzn zarejestrować osobno POST i osobno GET. Nie wiem, czy ja niewyraźnie napisałem?

IK
  • Rejestracja:ponad 7 lat
  • Ostatnio:prawie 2 lata
0

Nie ma łatwego sposobu na to.
Jeśli nie pytasz z czystej ciekawości, to mamy tu problem xy. Po co chcesz taką separację? Piszesz w Django, to pisz w Django, nie wciskaj tu springa czy innych pehapów.

Riddle
Administrator
  • Rejestracja:prawie 15 lat
  • Ostatnio:około 4 godziny
  • Lokalizacja:Laska, z Polski
  • Postów:10078
0
iksde napisał(a):

Nie ma łatwego sposobu na to.

Jeśli nie pytasz z czystej ciekawości, to mamy tu problem xy.

Tworzę aplikację w Django, i staramy się stworzyć true-rest. Mam endpoint /user który ogarnia zupełnie inne rzeczy na GET /user i POST /user. Nie chcę takich różnych logik trzymać w jednym miejscu, a nie mam wyboru. Nawet jak je oddeleguję, to i tak chciałbym widzieć w urls.py że to są różne rzeczy.

Po co chcesz taką separację?

GETy i POSTy się rządzą różnymi prawami, nie widzę powodu żeby to razem trzymać, razem rozwijać i razem testować.

Piszesz w Django, to pisz w Django, nie wciskaj tu springa czy innych pehapów.

Dzięki za sugestie.

edytowany 1x, ostatnio: Riddle
IK
  • Rejestracja:ponad 7 lat
  • Ostatnio:prawie 2 lata
0

No to wybraliście złe narzędzie.

Riddle
Tak. Jeden z najpopularniejszych frameworków, wspierany przez 17 lat rozwoju, potężne community, 14 tysięcy zmergowany PRów, instalowany 3000 razy na godzinę jest złym narzędziem - a dlaczego, bo grupuje zasoby po endponcie, a nie metodzie. Dziękuję za Twoją wartościową opinię.
IK
Nie napisałem, że django to złe narzędzie. Po prostu nie wpasowuje się w wasze oczekiwania. Czyli jest złym wyborem. Dlaczego wybraliście akurat django?
Riddle
@iksde: Z pierdyliona innych technicznych powodów. Bezpieczny, rapid-development, content-management, łatwo skalowalny, elastyczny. Nie bierzesz pod uwagę setek rozwiązań w Django które są dopasowane do potrzeb idealnie. Skupiasz się na tym że zadałem pytanie na forum, i na podstawie tej jednej cechy oceniasz wybór frameworka jako zły. Again: dziękuję bardzo z Twoją kolejną bardzo wartościową opinię. Myślę że nie wybiorę już Django do moich projektów, przez tak silną wadę jaką jest brak rozwiązania z mojego pytania.
IK
No skoro macie jakieś założenie, które jest praktycznie niemożliwe do zrobienia za pomocą danego narzędzia, to chyba jest to złe narzędzie do waszych celów, nie? Albo akceptujecie trade-off ze względu na inne zalety tego narzędzia, albo go nie używacie.
Riddle
@iksde: Jeśli nie masz nic więcej dodania do dyskusji nt oddzielenia logiki mvc od urli w django, to dziękuję. Nie będziemy zmieniać frameworka dlatego że pasuje do naszych wymagań w 99.99%, a nie 100%. Nie będę więcej odpowiadał na komentarze nie związane z tematem.

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.