我正在创建一个应用程序,允许用户输入股票交易,以保存记录。我使用 Django 的默认用户模型进行登录和身份验证。我的目的是允许登录用户仅查看他们自己的“条目”,这是我的库存记录条目模型。为此,我在名为“trader”的 Entry 模型中创建了一个一对多关系,该关系指向用户 ID(它们应该相同)。
登录后,即使已输入,我在屏幕上看不到任何交易。我检查了数据库,Entry.trader.id 与 User.id 的编号相同(在创建的第一个用户的情况下为 1)。很奇怪。
我尝试过的:我尝试从我的views.py EntryView类中删除这一行:
entries = Entry.objects.filter(trader_id=logged_in_user).order_by("entered_date")
并将其替换为:
entries = Entry.objects.all()
这有效(证明记录在那里),但现在它显示所有条目。
我的模型.py:
from django.db import models
from django.core.validators import MinValueValidator, MaxValueValidator
from django.urls import reverse
from django.utils.text import slugify
from django.contrib.auth.models import User
class Entry(models.Model):
ONEORB="1-Min ORB"
FIVEORB="5-Min ORB"
ABCD="ABCD"
REVERSAL="Reversal"
PROFIT="Profit"
LOSS="Loss"
RESULT_CHOICES = (
(PROFIT, "Profit"),
(LOSS, "Loss")
)
STRATEGY_CHOICES = (
(ONEORB,"1-Min ORB"),
(FIVEORB,"5-Min ORB"),
(ABCD,"ABCD"),
(REVERSAL,"Reversal")
)
entered_date=models.DateField(auto_now_add=True)
ticker=models.CharField(max_length=8, default="")
strategy=models.CharField(max_length=12, choices=STRATEGY_CHOICES, default="ONEORB")
result=models.CharField(max_length=6, choices=RESULT_CHOICES, default="PROFIT")
comments=models.TextField(max_length=300, blank=True)
image = models.ImageField(upload_to="", null=True, blank=True) #will save to default BASE_DIR which is 'uploads'
trader = models.ForeignKey(User, on_delete=models.CASCADE, null=False, blank=False, related_name="entries")
def __str__(self):
return f"{self.result} {self.entered_date}"
我的观点.py:
from django.forms.models import BaseModelForm
from django.shortcuts import render, redirect, get_object_or_404
from django.http import HttpResponse, HttpResponseRedirect
from django.views import View
from django.contrib import messages
from django.urls import reverse_lazy
from .forms import EntryForm, CreateUserForm, LoginForm
from .models import Entry
from django.views.generic.edit import DeleteView, FormView
# Authentication models and functions
from django.contrib.auth.views import LoginView, LogoutView
#this is to ensure that even after you have your login setup, a user can't just manually type in the URL
from django.contrib.auth.mixins import LoginRequiredMixin
# Create your views here.
class EntryView(LoginRequiredMixin, View):
login_url = 'login'
def get(self, request):
logged_in_user = request.user.id
entries = Entry.objects.filter(trader_id=logged_in_user).order_by("entered_date") #trader"_" id instead of .id is just django syntax
#entries = Entry.objects.all()
form = EntryForm()
return render(request, "entries.html", {"form":form, "entries":entries, "user":logged_in_user})
def post(self, request):
form = EntryForm(request.POST, request.FILES) #must add request.FILES for uploads
if form.is_valid():
form.save()
messages.success(request, "Entry created!")
return redirect("/")
else:
messages.error(request, "Please correct the errors below.")
return render(request, "entries.html", {"form":form})
def SingleEntryView(request, pk):
entry = Entry.objects.get(pk=pk)
if request.method == 'POST':
# Initialize the form with the existing Entry data
form = EntryForm(request.POST, request.FILES, instance=entry)
if form.is_valid():
# Set the user and save the updated data
form.instance.user = request.user
form.save()
# Redirect to a success page (e.g., 'index')
else:
# Initialize the form with the existing Entry data
form = EntryForm(instance=entry)
context = {'form': form, 'entry': entry}
return render(request, "single_entry.html", context)
class SingleEntryDeleteView(LoginRequiredMixin, DeleteView):
template_name = "single_entry.html"
model = Entry
success_url = reverse_lazy("index")
success_message = "Entry has been deleted."
def delete(self, request):
messages.success(self.request, "Successfully deleted.")
return super().delete()
def register(request):
form = CreateUserForm()
if request.method == "POST":
form = CreateUserForm(request.POST)
if form.is_valid():
print("User data created")
form.instance.user = request.user
form.save()
return redirect("/")
else:
form = CreateUserForm()
context = {'registerform':form}
return render(request, "register.html", context)
# class RegisterFormView(FormView):
# form = CreateUserForm
# template_name = "register.html"
# success_url = "/"
# def form_valid(self, form):
# form.save()
# return super().form_valid(form)
class LoginUserView(LoginView):
form = LoginForm
redirect_authenticated_user = True
template_name = "login.html"
next_page = "/"
authentication_form = LoginForm
context = {'form':form}
def form_invalid(self, form):
messages.error(self.request, 'Invalid usename or password')
return self.render_to_response(self.get_context_data(form=form))
我的条目.html(索引页):
{% extends 'base.html' %}
{% if messages %}
<ul class="messages">
{% for message in messages %}
<li{% if message.tags %} class="{{ message.tags }}"{% endif %}>{{ message }}</li>
{% endfor %}
</ul>
{% endif %}
{% block title %}
Trading Journal
{% endblock title %}Trading Journal
{% block content %}
<form method="POST" enctype="multipart/form-data" action="/">
{% csrf_token %}
{{ form }}
<button>Submit</button>
</form>
<h1>Request.user.id:{{request.user.id}}</h1>
{% endblock content %}
{% block table %}
<table class="blueTable">
<thead>
<tr>
<th>Date</th>
<th>Ticker</th>
<th>Strategy</th>
<th>Result</th>
<th>Comments</th>
</tr>
</thead>
<tfoot>
<tr>
<td colspan="5">
<div class="links"><a href="#">«</a> <a class="active" href="#">1</a> <a href="#">2</a> <a href="#">3</a> <a href="#">4</a> <a href="#">»</a></div>
</td>
</tr>
</tfoot>
<tbody>
{% for entry in entries %}
<tr>
<td><a href="{% url 'single-entry' entry.id %}">{{entry.entered_date}}</a></td><td>{{entry.ticker}}</td><td>{{entry.strategy}}</td><td>{{entry.result}}</td><td>{{entry.comments}}</td></tr>
{% endfor %}
</tbody>
</tr>
</table>
{% if request.user.is_authenticated %}
<a href="{% url 'logout' %}"><button>Logout</button></a>
{% endif %}
{% endblock table %}
我的网址.py:
from django.urls import path
from django.contrib import admin
from . import views
from django.contrib.auth.views import LogoutView
urlpatterns = [
path("", views.EntryView.as_view(), name="index"),
path("entries/<int:pk>/delete", views.SingleEntryDeleteView.as_view(), name="single-entry-delete"),
path("entries/<int:pk>/", views.SingleEntryView, name="single-entry"),
path("register/", views.register, name="register"),
path("login/", views.LoginUserView.as_view(), name="login"),
path("logout/", views.LogoutView.as_view(next_page="login"), name="logout"),
path("admin/", admin.site.urls)
]
我的forms.py:
from django import forms
from .models import Entry
# Authentication modules start here
from django.contrib.auth.forms import UserCreationForm, AuthenticationForm
from django.contrib.auth.models import User
from django.forms.widgets import PasswordInput, TextInput
# Form to create a journal entry
class EntryForm(forms.ModelForm):
class Meta:
model=Entry
exclude = ["trader"]
# Create / register a user
class CreateUserForm(UserCreationForm):
class Meta:
model = User #default django User model
fields = ['username', 'email', 'password1', 'password2']
# Authenticate a user
class LoginForm(AuthenticationForm):
username = forms.CharField(widget=TextInput())
password = forms.CharField(widget=PasswordInput())
我假设我的模型在定义“Entry”模型时会为“trader”分配一个值,但现在我发现我需要在我的视图中显式地为其分配一个值。在调用 form.save() 之前,我已在 view.py 中添加了这一行:
if form.is_valid():
form.instance.trader = request.user
form.save()