2017-10-28 21 views
7

Mam projekt django ecommerce, który działa poprawnie, dopóki nie postanowiłem go poprawić. Pozwalam użytkownikom składać zamówienia na określone usługi, ale za każdym razem, gdy składają zamówienie, muszą zawsze wprowadzać swoje dane (imię, nazwisko, imię i nazwisko, adres itp.), Więc postanowiłem uaktualnić aplikację, aby użytkownik mógł dodać swój adres rozliczeniowy i można się do niego odwołać w kolejności lub kontynuować jako gość.Rozszerzenie modelu użytkownika Django w aplikacji e-commerce

model

class Order(models.Model): 
    first_name = models.CharField(max_length=50) 
    last_name = models.CharField(max_length=50) 
    email = models.EmailField() 
    address = models.CharField(max_length=250) 
    postal_code = models.CharField(max_length=20) 
    city = models.CharField(max_length=100) 
    created = models.DateTimeField(auto_now_add=True) 
    updated = models.DateTimeField(auto_now=True) 
    paid = models.BooleanField(default=False) 

class OrderItem(models.Model): 
    order = models.ForeignKey(Order, related_name='items') 
    product = models.ForeignKey(Product,related_name='order_items') 
    price = models.DecimalField(max_digits=10, decimal_places=2) 
    quantity = models.PositiveIntegerField(default=1) 

widok

def order_create(request): 
    cart = Cart(request) 
    if request.method == 'POST': 
     form = OrderCreateForm(request.POST) 
     if form.is_valid(): 
      order = form.save() 
      for item in cart: 
      OrderItem.objects.create(order=order, product=item['product'],price=item['price'], quantity=item['quantity']) 
      cart.clear() 
      return render(request,'order/created.html', {'order': order}) 
    else: 
     form = OrderCreateForm() 
    return render(request, 'order/create.html',{'cart': cart, 'form': form}) 

Potem stworzył aplikację konta i rozszerzony użytkownika django tak, że użytkownik może zarejestrować adres i telefon komórkowy, dzięki czemu użytkownik nie musi wpisz go za każdym razem, gdy chce złożyć zamówienie.

mój nowy modelu jest

class Order(models.Model): 
    account = models.ForeignKey(Account, related_name='user_account') 
    created = models.DateTimeField(auto_now_add=True) 
    updated = models.DateTimeField(auto_now=True) 
    paid = models.BooleanField(default=False) 
    coupon = models.ForeignKey(Coupon, related_name='orders',null=True,blank=True) 
    discount = models.IntegerField(default=0,validators=[MinValueValidator(0), MaxValueValidator(100)]) 

Jestem zdezorientowany, jak kodować moim zdaniem. wszelka pomoc pomogłaby i mam również

def admin_order_detail(request, order_id): 
    order = get_object_or_404(Order, id=order_id) 
    #account = Account.objects.filter(request.user) 
    context = { 
     'order': order, 
     } 
    template = 'order/detail.html' 
    return render(request,template,context) 

aby móc zobaczyć szczegóły zamówienia w zakresie administracyjnym, ale jestem tylko w stanie przedłużyć imię i nazwisko, e-mail i numer telefonu. Każda pomoc będzie doceniona. Dzięki z góry

Kopia wszystkich kodów z github https://github.com/Olar19/ecommerce

+0

Prawdopodobny duplikat [Rozszerzanie modelu użytkownika o niestandardowe pola w Django] (https://stackoverflow.com/questions/44109/extending-the-user-model-with-custom-fields-in-django) – itzMEonTV

+0

To NIE jest duplikatem. – King

Odpowiedz

0

Jest to świetny pomysł na wykorzystanie wbudowanego w obiekt użytkownika. Django ma bardzo "baterie w zestawie", co oznacza, że ​​ma o wiele więcej gotowych rozwiązań niż Flask, a dla mnie duża część tego systemu autoryzacji użytkownika.

Zazwyczaj można rozszerzyć obiekt użytkownika za pomocą pola "jeden do jednego", które w twoim kontekście wygląda jak obiekt Konto.

more detail on one-to-one fields (from the docs)

Jeśli były wice B2B B2C to może warto obiekt konta do umieszczenia nazwy firmy, a następnie przypisać pracowników do tego konta, gdzie obiekt Pracownik będzie wówczas przedłużenie od Użytkownika.

Więc zakładając obiekt konta wyglądał:

class Account(models.Model): 
    user = models.OneToOneField(User, on_delete=models.CASCADE) 
    bio = models.TextField(max_length=500, blank=True) 
    ... 

Można wtedy dostęp do konta i użytkowników obiektów z Przedmiotu Zamówienia.

order = get_object_or_404(Order, id=order_id) 
username = order.user_account.username 

lub uprawnienia typu rzeczy

orders = Order.objects.filter(user_account__user = request.user) 
+0

Nie sądzę, że możesz uzyskać dostęp do 'order.user_account', ponieważ' related_name' jest przydatne dla odwrotnej relacji. Również w 'Order.objects.filter (user_account__user = request.user)' – itzMEonTV

+0

Tak. To nie działa – King

+0

Czuję się głupio, więc proszę mi pomóc. Obiekt zamówienia ma relację downstream do obiektu konta. Konto ma użytkownika "jeden do jednego". Więc nie zadziała, jeśli zamiast konta user_account wystarczy użyć konta ... nazwa_użytkownika = order.account.user.username. Innymi słowy, myślę, że zadziała, jeśli odniesiesz się do konta za pomocą "konta" vice "user_account". Jeśli to nie zadziała, zbuduję fałszywą aplikację i zobaczę, dlaczego nie działa. Przepraszamy za rozwalone rozwiązanie. – sahutchi

0

można użyć

order.account.user 

jeśli chcesz dołączyć od celu użytkownik musi użyć konta (nazwę pola nie związane name)

jeśli chcesz dołączyć z instancji konta t o zamówienia mogą wykorzystywać to:

account.user_account.all() 

powiązana nazwa jest nazwą dostępu odwróconego. Dostęp od powiązanego obiektu

więc jej lepiej wymienić nazwy związanej pola konto aby zlecenia

1

Co próbujesz zrobić coś bardzo powszechne i uzasadnione chcesz zrobić. Istnieją dwa główne sposoby dodawania dodatkowych informacji do modelu użytkownika Django. 1) Możesz przesłonić model użytkownika django i zdefiniować swój własny model lub 2) możesz utworzyć inny model, np. UserData, i UserData mieć połączenie OneToOneField z modelem użytkownika Django. W związku z tym dla każdego użytkownika istnieją powiązane dane UserData, które przechowują dodatkowe informacje o polu, których potrzebujesz. Trudno i nie zaleca się wykonywania opcji 1 w środku istniejącego projektu, więc zaleciłbym przejście do opcji 2.

Dokumentacja django jest bardzo dobra, jak stworzyć model UserData i połączyć go z użytkownikiem Model. Możesz przeczytać o tym here. Kluczową uwagą na temat tego podejścia jest to, że musisz: a) wrócić i utworzyć obiekt UserData dla wszystkich istniejących użytkowników (jeśli taki istnieje) oraz b) musisz upewnić się, że tworzysz obiekt UserData za każdym razem, gdy użytkownik zarejestruje konto użytkownika Twoja strona internetowa.

class UserData(models.Model): 
    user = models.OneToOneField(settings.AUTH_USER_MODEL, default=0, related_name="userdata") 
    # other fields ... 

Teraz w widokach, można uzyskać dostęp do danych użytkownika jako takie:

def admin_order_detail(request): 
    ud = request.user.userdata 

Po czym chcesz uzyskać dostęp do danych użytkownika w widoku, jest

Właśnie spojrzał Twój kod i wygląda na to, że obecnie nie używasz systemu użytkownika Django do rejestrowania się i logowania. Myślę, że pierwszym krokiem byłoby przeczytanie dokumentacji django w systemie autoryzacji użytkownika (here). Następnie spróbuj zintegrować autoryzację użytkownika z aplikacją. Na koniec możesz utworzyć niestandardową klasę userdata, aby rozszerzyć model użytkownika.

Powodzenia!

+0

Używam Django-allauth do mojego uwierzytelniania. Rozszerzanie modelu użytkownika nie jest problemem, z którym się borykam. Problem polega na tym, jak stworzyć system kasowy, który pobierałby zamówione produkty i sprawdzał, czy użytkownik przypisał adres wysyłki, czy też chce utworzyć inny adres wysyłki, aby wybrać dowolny przed przejściem do płatności. – King

+0

Możesz zobaczyć moje bieżące kody z mojego github, który zawarłem link w pytaniu – King

0

Myślę, że powinieneś po prostu utworzyć model konta rozszerzający usługę AbstractUser o adres e-mail, adres jako pole OneToMany, aby umożliwić jednemu użytkownikowi posiadanie wielu adresów. Adres może być model z polami jak

i nazwisko, adres, adres Linia 1 Linia 2, postal_code, miasto, województwo, Użytkownika (FK)

lub pojedynczego pola tekstowego zawierającego wszystko- info i user-fk.

Gdy użytkownik wybierze jeden ze swoich adresów, można po prostu dodać wpis adresu do modelu zamówienia dla tego odpowiedniego zamówienia, umożliwia to klientowi wybranie jednego lub więcej niż jednego już podanego adresu.

class Order(models.Model): 
    account = models.ForeignKey(Account, related_name='user_account') 
    address = models.ForeignKey(Address, related_name='address') 
    created = models.DateTimeField(auto_now_add=True) 
    updated = models.DateTimeField(auto_now=True) 
    paid = models.BooleanField(default=False) 
    coupon = models.ForeignKey(Coupon, related_name='orders',null=True,blank=True) 
    discount = models.IntegerField(default=0,validators=[MinValueValidator(0), MaxValueValidator(100)]) 

Umożliwia także nam odzyskać dane zarówno konta oraz adres dla danego zlecenia za pośrednictwem order.account i order.address.

Powiązane problemy